Version 28 (modified by adrian, 10 years ago) (diff)

Updated examples to reflect our latest thinking.

Fields as descriptors

This proposal changes the Django database API substantially.

The examples on this page use the following models:

class Reporter(models.Model):
    fname = models.CharField(maxlength=30)
    lname = models.CharField(maxlength=30)

class Site(models.Model):
    name = models.CharField(maxlength=20)

class Article(models.Model):
    headline = models.CharField(maxlength=50)
    reporter = models.ForeignKey(Reporter)
    sites = models.ManyToManyField(Site)


This proposal changes the way foreign-key and many-to-many related objects are accessed via the database-object API. It also changes the functionality of get_list(), get_object(), etc.

Under this proposal, each manager gets the following methods:

class Manager:
    def all(self):
        # returns a Query instance -- old get_list()

    def filter(self, **kwargs):
        # returns a Query instance -- old get_list(**kwargs)

    def get(self, **kwargs):
        # returns a Query instance -- old get_object()

    def values(self, **kwargs):
        # returns a ValuesQuery instance -- old get_values()

    def in_bulk(self, **kwargs):
        # return an InBulkQuery instance -- old get_in_bulk()

class Query:
    def filter(self, **kwargs):
        # returns a Query instance

    def unique(self, true_or_false):
        # returns a Query instance

    def order_by(self, *field_names):
        # returns a Query instance

    def count(self):
        # returns a Query instance

class ValuesQuery(Query):
    # Only difference is the output format.

class InBulkQuery(Query):
    # Only difference is the output format.

Any of these Manager methods can be overridden by custom managers, of course.

Related-object lookup uses the default manager of the related object, which means the API for accessing related objects is completely consistent with the API for accessing objects via a manager.

Another improvement is that the lookup type "__exact" can be left off.


Old syntax New syntax
Reporter.objects.get_list() Reporter.objects
Reporter.objects.get_list(fname__exact='John') Reporter.objects.filter(fname='John')
Reporter.objects.get_list(order_by=('-lname', 'fname')) Reporter.objects.order_by('-lname', 'fname')
Reporter.objects.get_list(fname__exact='John', order_by=('lname',)) Reporter.objects.filter(fname='John').order_by('lname')
Reporter.objects.get_object(pk=3) Reporter.objects.get(pk=3)
Reporter.objects.get_object(fname__contains='John') Reporter.objects.get(fname__contains='John')
Reporter.objects.get_list(distinct=True) Reporter.objects.distinct()
Reporter.objects.get_values() Reporter.objects.values()
Reporter.objects.get_in_bulk([1, 2]) Reporter.objects.in_bulk([1, 2])
Reporter.objects.get_in_bulk([1, 2], fname__exact='John') Reporter.objects.filter(fname='John').in_bulk([1, 2])
Many-to-one related lookup
article_obj.get_reporter() article_obj.reporter
reporter_obj.get_article_list() reporter_obj.article_set
reporter_obj.get_article_list(headline__exact='Hello') reporter_obj.article_set.filter(headline='Hello')
reporter_obj.get_article_count() reporter_obj.article_set.count()
reporter_obj.add_article(headline='Foo') reporter_obj.article_set.add(headline='Foo')
(Alternate syntax) reporter_obj.article_set.add(article_obj)
("values" lookup, etc., not previously possible) reporter_obj.article_set.values()
Many-to-many related lookup
article_obj.get_site_list() article_obj.sites
article_obj.set_sites([,]) article_obj.sites.clear(); article_obj.sites.add(s1); article_obj.sites.add(s2)
article_obj.set_sites([]) # deletion article_obj.sites.remove(s2)
site_obj.get_reporter_list() site_obj.reporter_set.all()
Back to Top