How Django orders class attributes
class BaseAttribute(object):
__creation_counter = 1
__def __init__(self):
____self.creation_counter = BaseAttribute.creation_counter
____BaseAttribute.creation_counter += 1
Required ordering for argument types
Descriptors
2 methods
class CurrentDate(object):
__def __get__(self, instance, owner):
____return datetime.date.today()
__def __set__(self, instance, value):
____raise NotImplementedError(“Can’t change date”)
class Example(object):
__date = CurrentDate()
e = Example()
e. date ## returns today
e. date = datetime.date.today()## raises error
instance - instance object containing attribute referenced, e in this case.
owner - class where descriptor was assigned. Example in this case
Descriptors short-circuit attribute access, so their values cannot be set with setattr - this would call the descriptor again and result in infinite recursion.
using __dict__ does the trick.
class Descriptor(object):
__def __init__(self, name):
____self.name = name
__def __get__(self, instance, owner):
____return instance.__dict__[self.name]
__def __set__(self, instance, value):
____instance.__dict__[self.name] = value
Common class and function attributes
Tracking subclasses
class SubclassTracker(type):
__def __init__(cls, name, bases, attrs):
____try:
______if TrackedClass not in bases:
________return
____except NameError:
______return
____TrackedClass._registry.append(cls)
class TrackedClass(metaclass=SubclassTracker):
__ _registry = []
class ClassOne(TrackedClass):
__pass
TrackedClass._registry
[<class>]</class>
etc….
Order of operations when processing model class
10 steps
metaclass for models is ModelBase. It is at django.db.models.base
Setting attributes on models
getattr() and setattr()
these are usually used, but one of Django’s hooks for model fields requires additional handling.
add_to_class()
a class method which checks the provided value for a contribute_to_class() method, calls if it exists. If it doesn’t, it uses setattr()
Pass any object in, it will be handled identically if you called setattr()
Getting Information about Models
Original structure can be determined via _meta attribute on every django model and instance.
Two groups of the above things
_meta has:
the last two deal with problems arising from not knowing the parent class of a given django model.
Starting off in the Django shell
from django.db.models.loading import cache
from django.db.conf.settings import *
cache. get_apps()
cache. get_app(‘viz’)
cache. get_models(cache.get_app(‘viz’))
cache. get_model(‘viz’, ‘optional’)
Common Field Attributes
21 total
Common Field Methods
16 (some were left out)
Subclassing Fields
5 methods on fields
Django uses duck typing for fields, or things that look like fields. You don’t have to inherit from fields at all.
How to call to_python() every time
from django.db.models.fields.subclassing import SubfieldBase
from django.db import models
class DurationField(models.DecimalField, metaclass=SubfieldBase)
__pass
__#field logic here