Django
Django is a high-level Python web framework. It has very good documentation at www.djangoproject.com.
from django.conf import settings
- Check version of Django installation by
import django; django.VERSION
. - Return data (not template) from view:
return HttpResponse(data)
- Show raw SQL of queryset:
print(qs.query)
- Run raw SQL:
from django.db import connection; cursor = connection.cursor(); cursor.execute(SQL)
. from django.contrib.auth.models import User as AuthUser
- To get a timezone-aware current time use:
from django.utils.timezone import now
Midnight isnow().replace(hour=0,minute=0,second=0,microsecond=0)
.
Gotchas
- Fixtures are only looked for in applications with
models.py
modules. - HTML
400 Bad Request
: WhenDEBUG
is false theALLOWED_HOSTS
check is made. SettingDEBUG
to true causes error to disappear! ImproperlyConfigured: The included urlconf [project].urls doesn't have any patterns in it
: Replacereverse
withreverse_lazy
. E.g. Class-based viewsuccess_url
is being evaluated before the URL patterns have been loaded.- Initially when a
ForeignKey
is instantiated with a string-based related field,self.rel.to
is set to the string-based identifier. It is later converted into the class proper. This can cause an errorisinstance() arg 2 must be a class...
.Fix is to ensure that the Model Cache is fully loaded:from django.db.models.loading import cache as model_cache
thenif not model_cache.loaded: model_cache._populate()
Admin
- Site-wide disable deletion on lists:
admin.site.disable_action('delete_selected')
inadmin.py
. - Specifying
blank=False
and adefault
value removes the empty choice from Admin interface. E.g.holiday_calendar = models.ForeignKey(Calendar, blank=False, default='ENG')
- Change List
- Filter using related data (works even for ManyToMany relationships):
list_filter = ['fieldname__relatedfieldname']
- Filter using related data (works even for ManyToMany relationships):
- Field
date_hierarchy = '[date_field]'
Adds a date-based navigation interface for that field.- Use
filter_horizontal = ('field_name',)
to get 2-pane many-to-many widget.
- Inline Admin
- Remove empty rows: By default Django displays three empty rows in each inline
list. To prevent this add
extra = 0
to the Inline admin declaration. - Remove Delete option:
can_delete = False
- Remove Add button:
max_num = 0
- Remove empty rows: By default Django displays three empty rows in each inline
list. To prevent this add
- Admin Template
- Object can be accessed as
original
. - Model as
opts
.
- Object can be accessed as
Fomfield For ForeignKey
The
formfield_for_foreignkey
method on a ModelAdmin allows you to override the default formfield for a foreign key field. For example, to return a subset of objects for this foreign key field based on the user:class MyModelAdmin(admin.ModelAdmin): def formfield_for_foreignkey(self, db_field, request, **kwargs): if db_field.name == "car": kwargs["queryset"] = Car.objects.filter(owner=request.user) return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
Commands
python manage.py runserver
Run Django development server. On a remote server usepython manage.py runserver 0.0.0.0:9000
; Project can then be visited using port9000
on the server's IP.python manage.py test [app][.TestCase[.test]]
Run unit tests.python manage.py shell
Start interactive Python shell with Django environment settings. Uses iPython if it is available.python manage.py dumpdata --indent 2 --format xml auth.user
Create fixture.python manage.py help
List all available manage commands.python manage.py startapp appname
Create a new application.
Reset Password using shell
python manage.py shell
from django.contrib.auth.models import User
u=User.objects.get(username__exact='[userid]')
u.set_password('[new_password]');
u.save()
Forms
- Bound Form: Initial data is ignored if a form is bound. (e.g.
form = SampleForm(request.POST))
. This means that it is impossible to update field contents in code. Django actually checks that theform.data[fieldname]
is immutable. - Pass error into validated form:
form._errors['fieldname'] = ErrorList([u'Error message'])
- Template
- Display field contents in template (works for ChoiceFields):
{{ form.instance.fieldname }}
- Access field id:
{{ field.auto_id }}
- Display field contents in template (works for ChoiceFields):
Models
get_or_create
looks for an existing entry where all the data matches. If one of these is a numeric then it must be rounded to match the database contents for this processing to work. Also timestamps of rows created in unit tests may differ by 1 second - can cause intermittent problems of attempting to create duplicates.- Proxy Models must be defined with the same
app_label
as the base model. Otherwise no permissions are found and access to the proxy is denied. - If a model has a ForeignKey, it will have access to a Manager that returns all instances of the keyed model. By default, this Manager is named
foo_set
, wherefoo
is the source model name, lowercased. This Manager returns Querysets.
IfClient
model has a many-to-many relationship toUser
then the following will return all the clients related to a specific user:request.user.client_set.all()
- You can reverse filter on ForeignKeys merely by referring to the other model by lowercase name. E.g.
Blog.objects.filter(entry__authors__name='Lennon')
.
Meta
- Ordering of objects in
models.py
will be used when listing objects on Admin pages. E.g.ordering = ['something__name', 'something_else__name']
verbose_name_plural
Natural Keys
A natural key is a tuple of values that can be used to uniquely identify an object instance without using the primary key value. They can be used to serialise data into fixtures to avoid the problem of needing foreign-keyed data to always have the same primary key.
Add a
get_by_natural_key
function to the model's manager which gets and returns the unique row which matches its parameters. Add anatural_key
function to the model to return the tuple of data which uniquely identifies a model instance.Serialise the data using
dumpdata
by adding a--natural
parameter.python manage.py dumpdata --natural --indent 4 cm > [app]/fixtures/initial_data.json
.Settings
LOGIN_REDIRECT_URL
Default:/accounts/profile/
. The URL where requests are redirected after login when thecontrib.auth.login
view gets no next parameter.
Templates
- Iterate through ManyToManyField contents with
.all
:{% for keyword in item.keywords.all %}{{ keyword }} {% endfor %}
TEMPLATE_STRING_IF_INVALID = 'Missing variable %s'
Display missing variables in templates.- Tags
{{ value|date:"[format]" }}
Format as date.{{ value|join:", " }}
Will output the items in list value separated by ", ".|safe
,|escape
and|escapejs
templatetags control how values are added to templates.|escapejs
Escapes characters for use in Javascript strings.- Don't put comma after last item:
{% if forloop.last %}{% else %},{% endif %}
- Return data (not template) from view: return HttpResponse(data)
from django.utils.html import strip_tags
Remove html tags from text.
Iterate through field choices
{% for id, label in form.banana.field.choices %} {{ id }}': '{{ label }}'{% if forloop.last %}{% else %},{% endif %} {% endfor %}
Views
- To return no data to a request use
return HttpResponse('')
- Return data (not template) from view:
return HttpResponse(data)
- User
getlist()
to retrieve list fromrequest.GET
. E.g.search_engine_ids = request.GET.getlist('search_engines', [])
- Use
from django.conf import settings
to access settings. This contains the application settings at runtime. - Show SQL which will be run by adding
query.__str__()
to queryset. - Return data (not template) from view:
return HttpResponse(data)
- Redirects:
from django.http import HttpResponseRedirect
thenreturn HttpResponseRedirect('/path/')
- Add
help = __doc__
to commands to reuse the docstring. @staff_member_required
: Decorator to ensure user is logged in and hasis_staff
set before allowing them access to a view. Import:from django.contrib.admin.views.decorators import staff_member_required
- Site-wide disable deletion on lists: