18👍
The first thing that pops up to my eyes is that in this case it is more common to import the Class, and not the module:
from models import UzbekistaniCitizen
person = UzbekistanCitizen.objects ...
Depending on if you use this kind of filtering very often, you might consider making your own custom model manager, so that it takes the following form:
#uses myfilter
person = UzbekistaniCitizen.objects.myfilter(hair__color=brown,
eye__color= blue,
height__gt= 56,
...
...
)
or anything else that might be more convenient in your case.
Note: after your edit, using managers still apply. The method myfilter doesn’t have to be made to emulate the filter function, and with managers you can do a lot more:
person = UzbekistaniCitizen.males.hair("brown").eyes("blue").income(50000)
It depends heavily on how you are planning on using it, and I wouldn’t make a custom manager just to keep the query shorter.
Between the two options you stated above, I prefer variant #1. I personally think it is more readable, with a glance I know what is happening. #2 just has way to many person’s and my eye has to do a bit more work to find the relevant methods being called to know what is actually happening.
There is variant number #3 that django uses itself in the examples:
Entry.objects.filter(
headline__startswith='What'
).exclude(
pub_date__gte=datetime.now()
).filter(
pub_date__gte=datetime(2005, 1, 1)
)
Although #3 is PEP 8 compliant…
The preferred way of wrapping long lines is by using Python’s implied
line continuation inside parentheses, brackets and braces. Long lines can be
broken over multiple lines by wrapping expressions in parentheses. These
should be used in preference to using a backslash for line continuation.
… I personally don’t like using hanging parenthesis like that in python, but as style decisions go: use what you feel more comfortable with, as long as it is readable and consistent.
48👍
You can use parentheses around the whole rhs to get implied line continuation:
person = (models.UzbekistaniCitizen
.objects
.filter(occupation__income__taxable__gte=40000)
.exclude(face__eyes__color=blue)
.order_by('height')
.select_related('siblings', 'children'))
- [Django]-What is a "Manager" in django?
- [Django]-Make django model field read only or disable in admin while saving the object first time
- [Django]-Django select only rows with duplicate field values
13👍
I’m not sure if you did it for illustrative purposes or not, but based on your example, remove all the additional calls to filter
and have just one filter
. When there’s a lot of arguments to a filter
, I also tend to use a dictionary which can be more naturally spread across lines:
person = UzbekistaniCitizen.objects.filter(**{
'hair__color': 'brown',
'eye__color': 'blue',
'height__gt': 56,
'age__lte': 30,
'job__income__taxable__gt': 40000,
}).select_related()
FWIW: this is also a handy method if you ever need to dynamically modify arguments to a filter
. Simply create a dictionary of the arguments, and you can append/change/delete items in the dictionary according to logic in your code. Then, you finally use it for the filter
: MyModel.objects.filter(**my_dict)
- [Django]-Raise 404 and continue the URL chain
- [Django]-Why is mod_wsgi not able to write data? IOError: failed to write data
- [Django]-How to use refresh token to obtain new access token on django-oauth-toolkit?
8👍
I have a nice style
person = (
models
.UzbekistaniCitizen
.objects
.filter(occupation__income__taxable__gte=40000)
.exclude(face__eyes__color=blue)
.order_by('height')
.select_related('siblings', 'children')
)
In this style, the most convenience is you do not have to indent by hand, every line indent is several 4 spaces.
Disadvantage of the below:
1. If you rename the variable person, you have to adjust indent by hand.
2. If your model name is very long, it is difficult to limit every line less than 80 characters.
person = UzbekistaniCitizen.objects.myfilter(hair__color=brown,
eye__color= blue,
height__gt= 56,
...
...
)
My style have other convenience:
1.can add comment:
person = (
models
.UzbekistaniCitizen
.objects
.filter(occupation__income__taxable__gte=40000) # your comment
.exclude(face__eyes__color=blue)
.order_by('height') # 2016-10-11 add
.select_related('siblings', 'children')
)
2.easy debug, you can comment some conditions easily
Below code can work fine. This is very useful in debug, you can comment condition line-by-line, rather than delete it and redo it.
person = (
models
.UzbekistaniCitizen
.objects
# .filter(occupation__income__taxable__gte=40000)
.exclude(face__eyes__color=blue)
# .order_by('height')
.select_related('siblings', 'children')
)
- [Django]-Determine complete Django url configuration
- [Django]-Django QueryDict only returns the last value of a list
- [Django]-Django required field in model form