Version 5 (modified by 10 years ago) ( diff ) | ,
---|
The new Options API proposal
As of my 2014 Summer of Code project, my second deliverable is a refactored working implementation of the Options API. The Options API is at the core of Django, it enables introspection of Django Models with the rest of the system. This includes lookups, queries, forms, admin to understand the capabilities of every model. The Options API is hidden under the _meta attribute of each model class. Options has always been a private API, but Django developers have always been using it in their projects in a non-official way. This is obviously very dangerous because, as there are no official endpoints, Options could change breaking other people's implementation. Options did not have any unit-tests, but the entire system uses it and relies on it to work correctly. My Summer of Code project is all about understanding and refactoring Options to make it a testable and official API that Django and any other developer can use.
Current state of the API
I now have a working and tested implementation of Options, I have managed to simplify 20+ functions and reduce them to 2 main endpoints, that are the main API. Because Options needs to be very fast, I necessarily had to add some accessors on Options for the most common calls (although both endpoints are cached, we can increase speed by avoiding function calls). Each accessor is a cached property and is computed, using the new API, on first access.
For this reason, I am planning to release in attached PR:
- Unit tests for the new Meta API
- The new Meta API
- The implementation of the new API throughout django and django.contrib
Concepts
Field types
There are 5 main types of fields:
Data fields
A data field is any field that has an entry on the database, for example a CharField, BooleanField, a ForeignKey
class Person(models.Model): # DATA field data_abstract = models.CharField(max_length=10)
M2M fields
A M2M field that is defined on the current model
class Person(models.Model): # M2M fields friends = models.ManyToManyField('self', related_name='friends', symmetrical=True)
Related Object
A Related Object is a one-to-many relation from another model (such as a ForeignKey) that points to the current model
class City(models.Model): name = models.CharField(max_length=100) class Person(models.Model): # M2M fields city = models.ForeignKey(City)
In this case, City has a related object from Person (as you can access person_set)
Related M2M
A Related M2M is a M2M relation from another model that points to the current model
class City(models.Model): name = models.CharField(max_length=100) class Person(models.Model): # M2M fields cities_lived_in = models.ManyToManyField(City)
In this case, City has a related m2m from Person
Virtual
Virtual fields do not necessarily have an entry on the database, they are "Django fields" such as a GenericRelation
class Person(models.Model): content_type = models.ForeignKey(ContentType, related_name='+') object_id_ = models.PositiveIntegerField() item = GenericForeignKey('content_type', 'object_id')
GenericForeignKey uses content_type and object_id to keep track of what model type and id is set by item, but item itself does not have a concrete presence on the database. In this case, item is a virtual field.
- Soc Status (second deliverable)
- Why
-The API
- get_fields
- get_field
- Fast access Calls
- fields -