====== Pro Django ======
Book: Pro Django 2nd ed. Apress
Try code:
source $_env/bin/activate
python manage.py shell
>>> import xxx
>>> def do_smt(xxx):
...
====== Django is Py ======
Base class
from django.db import models
class Contact(models.Model):
name = models.CharField(max_length=255)
email = models.EmailField()
Attribute Classes (CharField) look here:
vim refman_env/lib/python2.7/site-packages/django/db/models/fields/__init__.py
====== Models ======
===== Setting Attributes on Models =====
Python provides useful tools for getting and setting attributes on objects without knowing the name in advance, but
while getattr() and setattr() represent the standard way of accessing attributes on objects, one of Django’s hooks
for model fields requires some additional handling. Django provides a class method, add_to_class(), on all of its
models, which should be used as a substitute for setattr().
===== Getting infomation about models - _meta=====
==== Class information ====
Consider a situation where a model may be subclassed without inheriting all the Django-specific model
inheritance processing. This requires a bit of tweaking with metaclasses, but can prove useful for solving certain types
of problems. When doing this, the __name__ and __module__ attributes will refer to the child class, rather than the
actual model that sits underneath.
* _meta.module_name: module where the object is defined.
* _meta.object_name: name of the classes.
==== Field Definitions ====
Django uses the creation_counter technique described in Chapter 2 to keep track of the order
of fields, so they can be placed inside a list for future reference. This list is stored in the fields attribute of the model’s
_meta attribute.
_meta.get_field('fname') to get single field by name.
from django.utils.text import capfirst
def get_values(instance):
for field in instance._meta.fields:
name = capfirst(field.verbose_name)
value = getattr(instance, field.name)
print('%s: %s' % (name, value))
class Product(models.Model):
sku = models.CharField(max_length=8, verbose_name='SKU')
name = models.CharField(max_length=255)
price = models.DecimalField(max_digits=5, decimal_places=2)
def __unicode__(self):
return self.name
>>> from django.utils.text import capfirst
>>> for field in Product._meta.fields:
... print('%s: %s' % (capfirst(field.verbose_name), field.__class__))
...
ID:
SKU:
Name:
Price:
>>> Product._meta.get_field('name').__class__
=== Primary Key Fields ===
Django provides another _meta attribute, pk, which contains the field object that will be
used as the primary key for the model. This is also faster than iterating over all the fields, since pk is populated once,
when the model is first processed. After all, Django needs to determine whether it needs to provide an implicit
primary key. The _meta.pk attribute is also used to enable the pk shortcut property on model instances, which returns
the primary key value for an instance, regardless of which field is the primary key.
Django provides two attributes on the _meta attribute that help with this situation. The first,
_meta.has_auto_field, is True if the model let Django provide an id field implicitly. If it’s False, the model has an
explicit primary key, so Django didn’t have to intervene.
The second attribute related to the automatic primary key field is _meta.auto_field, which will be the actual
field object Django provided for use as the primary key. If _meta.has_auto_field is True, this will be an AutoField,
and will always be configured the same way for all models that use it. It’s important to look at this attribute instead of
making assumptions about the field’s structure, in case Django makes any changes in the future. It’s an easy way to
help make sure your application keeps working properly in the future. If a model provides its own primary key field,
and thus _meta.has_auto_field is False, _meta.auto_field will be set to None.
=== Configuration Options ===
abstract app_label db_table
=== Accessing the Model Cache ===
Once models have been processed by the ModelBase metaclass, they’re placed in a global registry called AppCache,
located at django.db.models.loading.
==== Retrieving All Applications ====
The first step in a site-wide introspection is to determine what applications are installed. Calling cache.get_apps()
will return such a list, containing the application module for each application in the INSTALLED_APPS setting that
contains a models module. That’s not to say that it only returns applications that have models. It actually checks for
the presence of a models module, so even an empty models.py will cause an application to be included in this list.
Take, for example, the following INSTALLED_APPS setting, showing several of Django’s own contributed
applications, as well as some in-house applications and the signedcookies application described in Chapter 7.
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'news',
'customers',
'callcenter',
'signedcookies',
)
Most of these applications will, by necessity, contain various models. Chapter 7’s signedcookies, however, only
interacts with the site’s HTTP traffic, so it has no use for the database. Therefore, when looking through the results of
cache.get_apps(), the signedcookies application won’t show up.
>>> from django.conf import settings
>>> from django.db.models.loading import cache
>>> len(settings.INSTALLED_APPS)
9
>>> len(cache.get_apps())
8
>>> for app in cache.get_apps():
...
print(app.__name__)
...
django.contrib.admin.models
django.contrib.auth.models
django.contrib.contenttypes.models
django.contrib.sessions.models
django.contrib.sites.models
news.models
customers.models
callcenter.models
==== Retrieving a Single Application ====
Django provides a utility for handling this situation. By passing the known label to cache.get_app(),
an application can retrieve the application module for just the application matching that particular label. The label
referred to here is determined as a specific part of the application’s import path.
Typically referenced as app_label, an application’s label is usually formed from the last part of the application
module’s import path before the models portion. To illustrate a few examples, consider the following application
labels, corresponding to the entries in the INSTALLED_APPS setting.
admin
auth
contenttypes
sessions
sites
news
customers
callcenter
signedcookies
As demonstrated earlier with cache.get_apps(), applications without models are viewed slightly differently
within Django itself than others. By default, cache.get_app() will raise an ImproperlyConfigured exception if the
application doesn’t contain a models.py file. Sometimes it may still be useful to process applications without models,
so cache.get_app() accepts an optional second argument to control how such applications are handled.
This second argument, called emptyOK, takes a Boolean indicating whether the application is allowed to not
contain any models. This defaults to False, which will raise the ImproperlyConfigured exception, but if True
is given instead, cache.get_app() will simply return None, allowing the calling code to continue managing the
application.
>>> from django.db.models.loading import cache
>>> print(cache.get_app('admin'))
>>> print(cache.get_app('signedcookies'))
Traceback (most recent call last):
...
django.core.exceptions.ImproperlyConfigured: App with label signedcookies could not be found
>>> print(cache.get_app('signedcookies', emptyOK=True))
None
==== Dealing with Individual Models ====
In the first case, consider pure introspection. Remember from the previous section that AppCache provides access
to all known applications with a single call to the get_apps() method, which returns application modules. Since these
modules are actually the models modules within each application, it may seem easy to just use dir(app_module) or
iterate over app_module.__dict__ to get the models that were defined.
cache.get_models() retrieves a list of proper Django models that are specific to the given application
module. It’s no coincidence that both cache.get_apps() and cache.get_app() return application modules;
cache.get_models() is suitable for use with both of these methods. That means that a list of models can be retrieved
even without an application, but knowing the application in advance reduces the number of models retrieved.
The following code demonstrates how these techniques can be used in combination to retrieve a list of models
for each of the known applications in use on the site.
>>> from django.db.models.loading import cache
>>> for app in cache.get_apps():
...
app_label = app.__name__.split('.')[-2]
...
for model in cache.get_models(app):
...
print('%s.%s' % (app_label, model.__name__))
...
admin.LogEntry
auth.Message
auth.Group
auth.User
auth.Permission
contenttypes.ContentType
sessions.Session
sites.Site
news.News
customers.Customer
callcenter.Agent
callcenter.Call
callcenter.Case
As an additional option, get_models() can also be called with no argument, which will cause it to return all the
models that are known to AppCache. This is a useful shortcut to avoid some of the overhead associated with the extra
loop in this example, as a quick way to grab all the models.
There’s a catch, however.
When using get_models() directly, with no argument, all registered models are returned. This may sound like a
great idea, and sometimes it is, but remember that AppCache registers all models as they’re encountered, regardless
of where they were found. The full list may include models that aren’t part of an installed application. Contrast that
with the get_apps()/get_models() combination, which only retrieves models if their applications are found in the
INSTALLED_APPS setting.
===== Using Model Fields =====
==== Common Fields Attributes ====
* attname
* blank
* choices: A sequence of 2-tuples indicating the valid choices for the field. The first item in
each tuple is the actual value that would be stored in the database if selected, while the second
item is the text that will be displayed to the user for that value.
* column
* db_column
* db_index
* db_tablespace
* ...
==== Common Field Methods ====
* clean(value, instance)
* contribute_to_class(cls, name)
* ...
===== Subclassing Fields =====
====== URLs and Views ======