Using django filters - python

I'm new to django so this must be a silly question but i was working my way through the official documentation tutorial(the one about a site with polls and choices) and i wanted to filter out polls with no choices, i managed to do that with a filter in the queryset argument of the ListView:
queryset=Poll.objects.filter(pub_date__lte=timezone.now).filter(id__in=Choice.objects.all).order_by('-pub_date')[:5]
And this indeed filters the query, the problem is that if i add a choice to a poll that didn't have any choices from the admin site, this won't be reflected on the site until i restart the server or i change some code in the project, even though i'm passing a callable object as argument to the filter (which is the same as the previous filter in that same line), i searched in the rest of documentation and i also looked at the definitive guide to django but i found nothing, that could help me, so i don't really know if there's something wrong with the code, or i'm lacking some understanding of django or a particular concept of python itself

Your current query is incorrect because, You are filtering poll ids, if choice objects of the same ids are present in the database, which is not accurate.
To filter out polls with no choice, you need to do
queryset=Poll.objects.filter(choice__isnull=False).order_by('-pub_date').distinct()[:5] #Get only polls with a choice.
Now,every Poll before now can be filtered like this:
queryset = Poll.objects.filter(choice__isnull=False, pub_date__lte=timezone.now()).order_by('-pub_date').distinct()[:5]

Related

Django modelform: Create new related object

I've been searching stack overflow and google for a solution for over an hour now, and I can't seem to find something that, in my opinion, should be easy to obtain (as it's a common use case).
I've checked this thread, and a few others, but I haven't been able to find a real, easy solution:
Django modelform: is inline adding related model possible?
Anyway, say I have a model with three related entities, two foreign keys and a many-to-many related class. Now, I have a ModelForm which displays these in comboboxes and lists, but what I need is that "+" button next to these elements (as seen in the admin interface).
I want the plus to take me to a new form, for that particular entity, allow me to submit the new information, create the database entry, take me back to my original form and have the newly added entity selected in the combobox. I'm really hoping the django ModelForm Meta class has an attribute that I can't seem to find which enables exactly this.
This isn't really a django question.
This has to do with presentation of a particular widget in an html document, and that is governed by either the HTML markup, CSS, or javascript.
Django is a server side application and is primarily responsible for creating a valid http response and receiving a valid http request (of course, there is a lot that happens in the interim and that is why django is so big) but it's not a "one toolkit to kill them all" app.
I think you want to look at bootstrap: http://getbootstrap.com/
Jquery UI: http://jqueryui.com/
Or some combination of the two.
You can also just mark up the document yourself with a stock img or something.
However, if you want to do it exactly how the admin does it, just go into django.contrib.admin and examin the code to figure out how the django developers did it. I believe they are just using Jquery UI and some manual markup to accomplish that.

Django - passing user related information to many views

I would like to view some user information on over half of my website's views.
This information should contain not only trivial username but also some fields from other tables of my project that are associated with current user.
I would also like to put this information into the template that my current view extends, just to keep it DRY.
I already did some research and coded some templatetags hoping that registering tags would help me achieve this but I have no idea how to get user information when there's no request like in views' functions.
Any tips on how to achieve this will be much appreciated. I just started django yesterday and am still a bit confused by it's philosophy.
You can use a context processor to add data to the template context in a DRY way.
In a nutshell, a context processor is simply a function that accepts a request as its first argument, does some additional processing that you add and augments the context with whatever values you want.
You can query an objects models, add the current datetime...pretty much anything you can do with Python or Django can go into a context processor.

How to filter autocompletion results in django grappelli?

We have a soft delete scheme where we just mark things as deleted and then filter the deleted ones out in various places. I'm trying to figure out how to filter the deleted ones out of the grapelli autocomplete suggestions.
In the end I went with this:
from grappelli.views.related import AutocompleteLookup
class YPAutocompleteLookup(AutocompleteLookup):
""" patch grappelli's autocomplete to let us control the queryset
by creating a autocomplete_queryset function on the model """
def get_queryset(self):
if hasattr(self.model, "autocomplete_queryset"):
qs = self.model.autocomplete_queryset()
else:
qs = self.model._default_manager.all()
qs = self.get_filtered_queryset(qs)
qs = self.get_searched_queryset(qs)
return qs.distinct()
It can be installed by overriding the relevant url:
url(r'^grappelli/lookup/autocomplete/$', YPAutocompleteLookup.as_view(), name="grp_autocomplete_lookup"),
Make sure this is ahead of Grappelli in your urls.
If your working with the Admin site, you should take advantage of the ModelAdmin.queryset function:
https://docs.djangoproject.com/en/1.5/ref/contrib/admin/#django.contrib.admin.ModelAdmin.queryset
As I found out, changing the default model manager to restrict the results is a bad idea, causing all kinds of nasty problems. For example: preventing syncdb, shell or shell_plus from running. Making it impossible to add the first record to a blank db. The exact errors depend upon what your restricting, but you are bound to get a few.
What is needed here is a way to tell Grappelli the name of the queryset manager to use. Passed in or a setting perhaps?
You can specify a simple (constant or related field) filter using ForeignKey.limit_choices_to. Grappelli grabs this value and sends it in the GET as param 'query_string'.
However, this might not be enough. I posted a request to the Grappelli repo I use to add a way to specify the record manger to use, or just automatically use the admin queryset (ModelAdmin.queryset).
My post is here:
https://github.com/sehmaschine/django-grappelli/issues/362
It looks like you can pass extra search params into the ajax autocompleter somehow. Likely a frontend hack needed.
https://github.com/sehmaschine/django-grappelli/blob/master/grappelli/views/related.py#L101
OR
You can make the default Manager for the models return an already filtered list, and have places that need to explicitly see deleted items remove that restriction.
This would likely make the default case much easier for you across the board.

Django: Get notified of all changes in database

I was wandering if there's a way to get notified of any changes to objects in a Django database. Right now I just need an email if anybody adds or changes anything but it would be best if I could hook a function triggered by any change and could decide what to do.
Is there an easy way to do it in Django?
Two ideas come to mind:
Override the predefined model method for saving.
Use a signal like post_save.
Here is a good article that talks about the difference between the two things listed above and when to use them:
Django signals vs. custom save()-method
The article was written near the end of 2007, three days after the release of Django 0.96.1. However, I believe the advice the author gives still applies today.

URLs stored in database for Django site

I've produced a few Django sites but up until now I have been mapping individual views and URLs in urls.py.
Now I've tried to create a small custom CMS but I'm having trouble with the URLs. I have a database table (SQLite3) which contains code for the pages like a column for header, one for right menu, one for content.... so on, so on. I also have a column for the URL. How do I get Django to call the information in the database table from the URL stored in the column rather than having to code a view and the URL for every page (which obviously defeats the purpose of a CMS)?
If someone can just point me at the right part of the docs or a site which explains this it would help a lot.
Thanks all.
You dont have to to it in the flatpage-way
For models, that should be addressable, I do this:
In urls.py I have a url-mapping like
url(r'(?P<slug>[a-z1-3_]{1,})/$','cms.views.category_view', name="category-view")
in this case the regular expression (?P<slug>[a-z1-3_]{1,}) will return a variable called slug and send it to my view cms.views.category_view. In that view I query like this:
#render_to('category.html')
def category_view(request, slug):
return {'cat':Category.objects.get(slug=slug)}
(Note: I am using the annoying-decorator render_to – it is the same as render_to_response, just shorter)
Edit This should be covered by the tutorial. Here you find the url-configuration and dispatching in every detail. The djangobook also covers it. And check pythons regex module.
Of course you can use this code.
Your question is a little bit twisted, but I think what you're asking for is something similar to how django.contrib.flatpages handles this. Basically it uses middleware to catch the 404 error and then looks to see if any of the flatpages have a URL field that matches.
We did this on one site where all of the URLs were made "search engine friendly". We overrode the save() method, munged the title into this_is_the_title.html (or whatever) and then stored that in a separate table that had a URL => object class/id mapping.ng (this means it is listed before flatpages in the middleware list).

Categories

Resources