When viewing model entries from within Django Admin, you can specify filters. How can I mimic this behavior? Not to familiar with kwargs but something similar to this:
foo = Model.objects.filter(**__exact='**')
where the first set of ** would be a field in the model and the second set would be an entry. Basically making the queries variable, based on what the user chooses on the front end. How would I send that variable sort option to the view, and then return it back to the webpage. What about using a dictionary? Please help
This SO question has proven to be a little helpful, but still cannot grasp it completely.
You can unpack a python dict as your filter parameters using **
your_filters = {
'field_1__exact': value_1,
'field_2__gte': value_2,
}
Model.objects.filter(**your_filters)
Said that, you can built your query filters(a python dict) dynamically based on an user input.
Related
Using an example close to the one from the many to many relationship example in the book:
db = DAL("sqlites://storage.sqlite")
db.define_table('persons',
Field('name'))
db.define_table('things',
Field('name'))
db.define_table('ownership',
Field('person', 'reference persons'),
Field('thing', 'reference things'))
I have an additional table :
db.define_table('usages',
Field('person', 'reference person',requires = IS_IN_DB(db, db.person.id, '%(name)s'),
Field('thing', 'reference thing'),
Field('usage'))
For the table usages I want to have dropdown menus for both person and thing fields hence the use of requires .....
However I would like to have the dropdown menu from thing to changes according to the selection in person (to limit the choice to things a person owns).
I thought about using requires as i did to get the dropdown menu, however I cannot use db.usages.person in a requires = IS_IN_DB(...) because the entry is not created and therefore it throws an exception.
What I tried :
requires = IS_IN_DB(db, db((db.usages.person == db.persons.id) &(db.persons.id == db.ownership.person) &(db.ownership.person == db.things.name)))
Using requires = IS_IN_DB(db,db.things.id, '%(name)s') gives me a dropdown menu for thing but it lists all of the them regardless of the selection in person.
Any idea on how to solve this?
There is no built-in way to do what you want. You will need to use Javascript to (a) detect when a selection is made in the person field, and (b) make an Ajax request to the server to fetch a list of options for the thing select element.
For some examples, check out these posts on the web2pyslices site, and also check out plugin_lazy_options_widget.
Also, regarding your code:
requires = IS_IN_DB(db, db((db.usages.person == db.persons.id) &(db.persons.id == db.ownership.person) &(db.ownership.person == db.things.name)))
note, that the second argument to IS_IN_DB must be a Field object or field name, not a DAL Set object. If you want to limit the set of options via a filter, the first argument can be a Set object (though, as noted, that won't help in this case, as you don't know what the filter criterion will be until a selection is made in the browser).
I am extending product.template, and I've added a field called uom_class. When I change this field when editing a product, I'd like to clear what is entered in the Many2One field called "Unit of Measure" (uom_id in product.template). I am doing this because I am also changing the domain for the uom_id, and the existing selection ("Units" by default) will probably not be in that domain.
I've tried the following, as suggested for earlier versions, but it did not work.
#api.onchange('uom_class')
def onchange_uom_class(self):
# [...] not shown: previously set new domain for uom_id
result['value'] ={'uom_id':False}
return result
I've seen other posts suggest I need to add assign it an empty product.uom record, but I have no idea how to do that. Any help would be greatly appreciated.
Well, I figured this one out.
I just declared
uom_id = False
For some reason, returning the domain works, but not returning the value. Either that, or I just have no idea what I'm doing and I'm returning the value wrong... which is entirely possible.
I have a question about Django and it's routing system. I believe that it can be powerfull, but right now I am struggling with one issue I don't experience when working in other frameworks and I can't seem to get a grip on it. Worth to mention that I don't have much experience with Django at this point.
The issue is simple - I have a view which takes two optional parameters, defined like this
def test_view(id=None, grid=None):
Both parameters are optional and frequently are not passed. Id can only be an integer and grid will never be an integer (it is a special string to control datagrid when I don't want to use sessions). I have a route defined like this:
url(a(r'^test_view (\/(?P<id>\d+))? (\/(?P<grid>[^\/]+))? \/?$'), views.test_view, name='test_view'),
This works great and I am not having trouble with using one-way routes. But when I try to use the reverse function or url template tag, following error occurs:
Reverse for 'test_view' with arguments '('20~id~desc~1',)' and keyword arguments '{}' not found.
In this example I tried to find reverse without the id, just with the grid parameter. I have tried various methods of passing parameters to the reverse function:
(grid, )
(None, grid)
('', grid)
{id=None, grid=grid}
All of them result in same error or similliar one.
Is there a way to implement this in django? Maybe just disable the cool URL for the grid parameter. That is how I do it in for example Nette framework for PHP, isntead of having an url like this: 'localhost/test_view/1/20~id~desc~1' I have url like this: 'localhost/test_view/1?grid=20~id~desc~1'. This would be completely sufficient, but I have no idea how to achive this in Django.
As you note in your question, the best way to achieve this is to use standard GET query parameters, rather than doing it in the path itself. In Django you do that exclusively in the view; the URL itself is then just
url(r'^test_view$', views.test_view, name='test_view'),
and you request it via localhost/test_view?id=1&grid=20~id~desc~1. You get the params from request.GET, which is a dictionary-like object; you can use .get so that it does not raise a KeyError when the key is not provided.
def test_view(request):
id = request.GET.get('id')
grid = request.GET.get('grid')
I have a Django app that searches for data from a model Classified and displays them using simple querysets based on the input term. This works perfectly and I've got no complains with this method.
However, if someone enters a term that returns no data, I would like to provide an option with alternate/suggested search.
Eg: Someone searches 'Ambulance Services' which doesn't return data. I'd like to suggest 'Ambulance' or 'Services' as alternate search options which may return data from the model depending on the data present in the model.
I Googled suggested search in django and it gave me options of Haystack/elastic search, etc which I'm not sure are really required since the search is across just one model.
Note: SO tells me that my question may be closed as it is subjective. If thats the case, please suggest where I can move it to. Thank you!
This is just an idea, but might work for you:
The user enters the search data: "Ambulance Services"
If the query inside the view returns nothing, redirect to the same view using your selected alternative search data, lets say "Ambulance", and a flag value thats saids the view you're preforming a suggested search.
You must have two things in consideration:
What if the alternate search don't returns anything either? You have to set a recursion limit here.
How I'm going to select the data of the alternate search? Well, thats another question about a completly different topic.
This is this idea in code:
def search(request, data, alternate=False, recursion_level=3):
result = Classified.objects.filter(some_filed=data)
if 0 == result.count() and 0 != recursion_level: # Conditions needed for perform alternate search.
new_data = select_new_data(data) # The logic inside this function is up to you.
r_level = recursion_level - 1 # Decreas recursion level.
return redirect('search', alternate=True, recursion_level=r_level) # Redirecting using view name, you can use others
# forms of redirection see link below for visit
# the Djando redirect API doc.
else:
return_data = {}
if alternate:
# You can use this flag in order to reflect
# to the user you have performed an alternate search.
# Example:
return_data["alternate"] = True
# Build your return data.
# and render.
#return render_to_template()
Django redirect doc: redirect
Haystack is, indeed, a great option, here you will find how to give 'spelling suggestions', you can see an example in this OS question/answer
No matter you have only one model, this tool is really great, simple to install /set up/use, and very flexible.
Perhaps this helps as well.
I'm trying to use the get_list tastypie function but I can't make it work. I've looked for documentation about that but I can't find it.
Whatever, I've a list of item ids and an ItemResource. I'm trying to return a list of serialized objects.
So I just want to do something like that :
item_resource = ItemResource()
item_ids = my_item_id_list
return item_resource.get_list(request, id=item_ids)
But of course it's not working.
What would be the correct syntax to do that ?
Thx !
Unless your ItemResource accepts filters (more here), you have to copy-paste all the stuff from here, lines #1306 - #1313.
The point is that get_list results get filtered only by obj_get_list (initial filters), and apply_filters (request-specific filters) so you have to skip directly to the serialization part (you can include the pagination part, if needed).
This is one of the cases where django-restframework appears to be better than django-tastypie - it refactores serialization out into a separate class, avoiding the code duplication.