So I have a search page with result table. I have a drop down that's a filter from the DB. Instead of calling and populating this drop-down field filter at my view/index() method, can I just call a helper function that returns this list from the DB and populates the drop down at the template level?
I know about context_processors and my understand is that it's for the entire site, but I want this DB call to only happen on this particular page and no where else?
What do call this so I can try to find it in django docs.
Much Thanks
edit: to clarify more: the result table contains movies and drop-down filter is movie types (actions, adventure, thriller, etc). This list is made up from a "SELECT DISTINCT type FROM movies" query.
The Django equivalent of helpers is custom template tags, and it's certainly appropriate to put db-accessing code there.
However, if it's only for a single page, I'm not sure why you wouldn't do it in the view.
Related
What would be the correct approach to create a "stats block" which could be used easily?
I've now created a simple page template and view function which returns a list of stats e.g. users and user count by calling User.objects.all().count()
How should this be implemented to be able to include these stats in any template? And perhaps with different styles such as list, inline, bootstrap panel etc?
If you want it in any template, you probably want to write your own custom template tag. This is the relevant Django documentation: https://docs.djangoproject.com/en/2.2/howto/custom-template-tags/#writing-custom-template-tags
Your tag will probably return minimalist data: just the result of queryset.count(). The template that you are rendering will place this number in the relevant html context.
I have a page where I'm displaying the results of a queryset to the user.
What i'd like to do is allow the user to click on a link in order to apply a filter.
Currently what I do is have the links pass "get" parameters to the page in order to apply filters. The filters can be references to other models or custom filters (e.g. an unassigned filter)
In order to provide a decent user experience the implementation needs to do a few things
in the view:
check that the filter parameter passed is valid
check what type of filter it is (based on other models or a custom filter) in order to apply the correct condition to the queryset
(optional) a way to make the filters cumulative (i.e. you can keep adding filters)
in the Template:
display the correct resultset based on the filter choosen
when displaying the filters, recognize which filter we have applied so that the current applied filter is displayed as text not a hyperlink.
I'm thinking this must be common enough that someone must have like a design pattern or best practice figured out for this other than the obvious whack of if/else statements in the view and the template.
is there?
I find the way the Django admin handles this kind of functionality a great pattern. If you're not familiar, check out the list_filter option in the admin. It's similar to what you're describing, but yours is a bit more generic. Perhaps this will help you ponder some ideas?
First, for the actual querystring chunk, you're simply passing the Django-ORM lookup key and value pair. e.g., ?sites__id__exact=1, tags__in=words, etc. Since you want to allow for cross-model lookups, you'd need to provide another parts in the string to include the model name, not too tough.
For checking if the filter is valid, you can simply ensure that the model/field lookup is valid. By splitting the parts of each QS chunk, you can identify the model, the fieldname, the lookup, and the value. Then, use Django's built-in functionality to validate that fieldname exists on model. You can do this with ForeignKey's too. Here's how Django does it
You can keep adding filters pretty easily to this. You'll be providing your view and the form that's displaying these filters with some context, so it'll persist and re-populate for the user. Also, you could just as easily persist the query string. Basically, you'd have the same read / parsing functionality here at all times, nothing really different.
I think the keys are automating and keeping it as DRY as possible. Don't succumb to a bunch of if statements. It's really easy to pass these lookups into the ORM, safely too, and it's really easy to catch bad lookups and provide the user with a meaningful error message.
I hope that helps you on your path! :)
It is my understanding that template tags are a way to organize presentation logic, is this correct?
What I want to do is load/read a bunch of my model objects, but show them in different areas of the template according to a filter.
The first thought was to implement a tag get_myobjects_by_filterx but then I have to implement it for each filter I have, and I would use it by calling the tag on the areas of my template where I want them to show up.
So the second thought was to move the filterx into the tag itself, so the call would be get_myobjects_by "X" (passing the filter as string) then in the tag filtering and returning. Is this the prefered way? What if I need to pass another object not just a string?
Could I use a filter instead?
Little more detailed what I want to do: Load a kind of my objects and filter it by some of its fields, depending on which filter is applied, show it in different areas of my template. For example I want "if objects filtered by X show all of those in the column x else in column y and so on".
How do I solve this kind of question with django?
Thanks.
As far as my understanding goes, template tags are nothing but some python functions which can be used inside the templates. Because a django template is not your normal python program.
Is it possible to reuse a template dictionary in another view ?
For instance, imagine a view performs a search on the db and provide the search results in a dictionary to a template. The template displays the first 10 results and has a link to display all the results in another page.
Is it possible to forward the template dictionary containing the search results to avoid having to perform the same search again ?
Not really. You can't preserve anything across page views - except by storing it somewhere, eg in the session. You couldn't put it in the template itself, as that would then need to be sent back to the server via a POST for the next request.
In any case, there's not much need to do this. If you use the built-in Paginator class to paginate your search, Django will automatically use LIMIT and OFFSET in the query so that only the objects you're actually displaying will be queried.
In an inline form, in the admin interface, I have a foreign key field.
If you look at the following image: http://www.image-share.com/ipng-147-172.html you will notice an engine field (Set to proximity).
What I'd like is to filter what appear in the list (currently track.context.max_media_duration and track.ambient.max_media_duration) bases on the engine selection.
I'd like it to change when the selection is changed, it will also have to mark existing one that has been filtered out for deletion or delete them.
I don't know where to start to implement such a feature.
Thanks
The easiest approach, in my opinion, would be to do it all as an AJAX callback (e.g. with jQuery). The general code flow might be the following:
Add a jQuery onChange event to the id_engine field.
When the id_engine pull down changes, it triggers a callback.
That callback calls a URL you have set up back to a specific URL and returns values as JSON data.
These values are what you use to overwrite what is found in the pull downs below... jQuery can overwrite these pretty simply. You just have to be careful to match what Django outputs by default -- keeping form names and values similar so Django will know how to handle it when POSTing the data back.