Avoid repeating the same query for object list in each Django view - django

I have a product list in my site's main menu.
My site's main menu is defined in my base template.
The product list is not hardcoded in template and is queried from DB.
So my base template requires product list to be in the request context of each view.
What is the best way to avoid querieng for product list and putting result into the request context in each view?
Thanks.

You can use template_context_processors. Create file, for example context_processor.py, and write in it method with argument request. Method must return values, in your case, it is product list. Then in settings file in TEMPLATE_CONTEXT_PROCESSORS option add your file_name.method_name. And in the base html use variable, which was returned.

Related

Save the dynamically populated value on dropdown

I'm using wagtail CMS for Django, I want to add a dynamically populated value for a dropdown and save it on the Page model, this is my code:
class MyPage(Page):
domain = CharField(max_length=10, choices=MY_CHOICES)
subdomain = CharField(max_length=10, choices=[('', '------')]
I've got some frontend logic to populate dynamically the options for subdomain, but after I hit save I got: The page could not be created due to validation errors And in the subdomain field: Select a valid choice. [my value] is not one of the available choices.
I can't use ForeignKey to populate subdomain because it depends from an external API service that we're using.
I tried to use a custom field that inherits from CharField with no success, it looks it executes validate method only for the domain field.
If you use the choices argument, you have to predefine the list of possible values. Read the relevant part of the docs (last two paragraphs of that section).
You could omit the choices argument from the model field definition and only render a HTML select tag in the frontend (which is then filled with options dynamically, like you explained).
You could also look into changing the default widget of the CharField to a select tag, like this answer and this part of the docs show.

How can I pass a variable to all the HttpResponse?

I am learning Django and I want to list in all my pages the categories, that are for example categories = Category.objects.all(), but I think it's very redundant to declare that variable in all my views and pass it in every HttpResponse. Is there any way to do it for all?
If you want to add categories to all the pages it may be useful to write a custom template tag, https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#writing-custom-template-tags

How to make a dynamic menu in base template using django

I'm about to start a new project and I think this time django is the way to go. I've been reading the documentation for the past two weeks and it looks promissing.
Ok, the thing is that I could not find anything about (in C# MVC called) Partial Rendering. For example if I want a dynamic menu where the menu-items comes from the database, then I would expect that the base template (or master page) renders the menu on each request (the partial renderer invokes another action or renders a template with some session data). So, the menu comes for free as long as my template inherits from this base template.
Honestly, I have no clue on how to achieve this.
What I would like is some code in the base template that uses data that is not contained in the child template. I don't want to include an extra variable (maybe 'menu_list_items') every time I call render_to_response('child_content.html',context). Is this possible?
Thanks!
You could either use a context processor, or a custom template tag to provide this functionality.
A context_processor is a simple function which can add objects to every RequestContext. A custom template tag can have its own template snippet and context which could render the menu for you.
For the template reusing: you should just create a base template for the generic layout, and use detailed templates for the individual pages. This is already covered in detail by the Django documentation.
What I tend to do for those generic parts (say for example, a menu highlighting the current part of the site the use is on), is to create my own render_to_response functions, akin to the following:
from django.shortcuts import render_to_response as django_render_to_response
def render_to_response(template, params, context_instance):
return django_render_to_response(template,
AppendStandardParams(request, params),
context_instance)
The ApplyStandardParams method then configures the menu based on the current path:
def AppendStandardParams(request, params):
if request.META['PATH_INFO'].startswith('/customer'):
params['category'] = 'customer'
params['title'] = 'Customer overview'
# and so on for all different parts
These category and title tags in this example are some values used to highlight the menu, configure titles, and so on. For example:
<!-- Customer menu entry: change class if this is the current category. -->
<li{% if category == "customer" %} class="selected"{% endif %}>Customers</li>
Finally, to use it in a view, instead of the normal render_to_response import, I just do something like from lib.views import *, which makes my custom version available in the view. This way the syntax of all code in the views stays the same, but I don't have to customize the menu every time I create a new view or app.

django pagination: How to get number of page by id of element in the list

I use django-paginaton app and I'm very glad to use it. Now I need feature, that I don't know how to implement. I have list of elements, that paginated by django's paginator. I have one element with specified id, that I should show, but I don't know what page contains it. I need mechanism jump to the page, that contains my element.
I think it's a good idea if django-pagination will support this transparently and automatically. For example, I set special context variable page_by_id to X and if page is None, it will be defined to the value, that contains my X element.
What do you think about this mechanism?
May be there is another clean way to do this?
This is for continue of this questions:
Django pagination and "current page"
Django Pagination - Redirecting to the page an object is on
At least, I wrote patch for django-pagination that provide 2 features:
Get number of page by id of element inside paginated list;
Possibility to rename default parameter 'page' to another value for
using it inside template;
This works transparently by adding 2
optional parameters in autopaginate templatetag:
{% autopaginate object_list paginated_by orphans page_by_id parameter_name %}

Styling certain admin change list rows

Is there a straightforward, common way to apply custom styling on admin change list element depending on its properties?
update
To be more precise: let's say I have a simple model object.
Foo
field1
field2
field3
#property
property1()
#property
property2()
ModelAdmin.list_display is defined as a subset of the available fields, so not every attribute (field/property) is displayed in the change list table.
I'd like to apply custom CSS class to the object's row when certain condition is fulfilled, for example: if foo_instance.property1 is True then add class bar to the corresponding tr element.
Now copy the template admin/base_site.html from within the default Django admin template directory (django/contrib/admin/templates) into an admin subdirectory of whichever directory you're using in TEMPLATE_DIRS. For example, if your TEMPLATE_DIRS includes "/home/my_username/mytemplates", as above, then copy django/contrib/admin/templates/admin/base_site.html to /home/my_username/mytemplates/admin/base_site.html. Don't forget that admin subdirectory.
Note that any of Django's default admin templates can be overridden. To override a template, just do the same thing you did with base_site.html -- copy it from the default directory into your custom directory, and make changes.
from django's tutorial
What exactly do you mean by "change list element" and "it's properties"? Using CSS 2 or CSS 3 selectors you can do some things. Otherwise, you might be able to do it easily using jQuery (or whatever). Since it is merely presentation related, I think this would be the cleanest solution.
Old question but if you stumble across it, the following tips might be helpful.
You can use django-liststyle to customise your admin changelist rows.
It's quite simple to implement your example:
class FooAdmin(admin.ModelAdmin, ListStyleAdminMixin):
...
def get_row_css(self, obj, index):
if obj.property1:
return 'bar'
return ''
Django Suit (not free) also offers "List row and cell attributes" style customisation