2009-03-18 17:47:08 +08:00
|
|
|
"""
|
|
|
|
By specifying the 'proxy' Meta attribute, model subclasses can specify that
|
|
|
|
they will take data directly from the table of their base class table rather
|
|
|
|
than using a new table of their own. This allows them to act as simple proxies,
|
|
|
|
providing a modified interface to the data from the base class.
|
|
|
|
"""
|
|
|
|
from django.db import models
|
|
|
|
|
|
|
|
# A couple of managers for testing managing overriding in proxy model cases.
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-03-18 17:47:08 +08:00
|
|
|
class PersonManager(models.Manager):
|
2013-03-08 22:15:23 +08:00
|
|
|
def get_queryset(self):
|
2017-01-21 21:13:44 +08:00
|
|
|
return super().get_queryset().exclude(name="fred")
|
2009-03-18 17:47:08 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-03-18 17:47:08 +08:00
|
|
|
class SubManager(models.Manager):
|
2013-03-08 22:15:23 +08:00
|
|
|
def get_queryset(self):
|
2017-01-21 21:13:44 +08:00
|
|
|
return super().get_queryset().exclude(name="wilma")
|
2009-03-18 17:47:08 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-03-18 17:47:08 +08:00
|
|
|
class Person(models.Model):
|
|
|
|
"""
|
|
|
|
A simple concrete base class.
|
|
|
|
"""
|
|
|
|
name = models.CharField(max_length=50)
|
|
|
|
|
|
|
|
objects = PersonManager()
|
|
|
|
|
2012-08-12 18:32:08 +08:00
|
|
|
def __str__(self):
|
2009-03-18 17:47:08 +08:00
|
|
|
return self.name
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-03-18 17:47:08 +08:00
|
|
|
class Abstract(models.Model):
|
|
|
|
"""
|
|
|
|
A simple abstract base class, to be used for error checking.
|
|
|
|
"""
|
|
|
|
data = models.CharField(max_length=10)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
abstract = True
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-03-18 17:47:08 +08:00
|
|
|
class MyPerson(Person):
|
|
|
|
"""
|
|
|
|
A proxy subclass, this should not get a new table. Overrides the default
|
|
|
|
manager.
|
|
|
|
"""
|
|
|
|
class Meta:
|
|
|
|
proxy = True
|
|
|
|
ordering = ["name"]
|
2012-03-22 16:49:48 +08:00
|
|
|
permissions = (
|
|
|
|
("display_users", "May display users information"),
|
|
|
|
)
|
2009-03-18 17:47:08 +08:00
|
|
|
|
|
|
|
objects = SubManager()
|
|
|
|
other = PersonManager()
|
|
|
|
|
|
|
|
def has_special_name(self):
|
|
|
|
return self.name.lower() == "special"
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-03-18 17:47:08 +08:00
|
|
|
class ManagerMixin(models.Model):
|
|
|
|
excluder = SubManager()
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
abstract = True
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-03-18 17:47:08 +08:00
|
|
|
class OtherPerson(Person, ManagerMixin):
|
|
|
|
"""
|
2017-11-07 11:11:39 +08:00
|
|
|
A class with the default manager from Person, plus a secondary manager.
|
2009-03-18 17:47:08 +08:00
|
|
|
"""
|
|
|
|
class Meta:
|
|
|
|
proxy = True
|
|
|
|
ordering = ["name"]
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-03-18 17:47:08 +08:00
|
|
|
class StatusPerson(MyPerson):
|
|
|
|
"""
|
|
|
|
A non-proxy subclass of a proxy, it should get a new table.
|
|
|
|
"""
|
|
|
|
status = models.CharField(max_length=80)
|
|
|
|
|
2016-04-17 19:55:55 +08:00
|
|
|
objects = models.Manager()
|
|
|
|
|
2009-03-18 17:47:08 +08:00
|
|
|
# We can even have proxies of proxies (and subclass of those).
|
2013-11-03 05:34:05 +08:00
|
|
|
|
|
|
|
|
2009-03-18 17:47:08 +08:00
|
|
|
class MyPersonProxy(MyPerson):
|
|
|
|
class Meta:
|
|
|
|
proxy = True
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-03-18 17:47:08 +08:00
|
|
|
class LowerStatusPerson(MyPersonProxy):
|
|
|
|
status = models.CharField(max_length=80)
|
|
|
|
|
2016-04-17 19:55:55 +08:00
|
|
|
objects = models.Manager()
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
class User(models.Model):
|
|
|
|
name = models.CharField(max_length=100)
|
|
|
|
|
2012-08-12 18:32:08 +08:00
|
|
|
def __str__(self):
|
2009-05-11 18:10:03 +08:00
|
|
|
return self.name
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
class UserProxy(User):
|
|
|
|
class Meta:
|
|
|
|
proxy = True
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2016-03-28 03:20:54 +08:00
|
|
|
class AnotherUserProxy(User):
|
|
|
|
class Meta:
|
|
|
|
proxy = True
|
|
|
|
|
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
class UserProxyProxy(UserProxy):
|
|
|
|
class Meta:
|
|
|
|
proxy = True
|
|
|
|
|
2016-03-28 03:20:54 +08:00
|
|
|
|
|
|
|
class MultiUserProxy(UserProxy, AnotherUserProxy):
|
|
|
|
class Meta:
|
|
|
|
proxy = True
|
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
# We can still use `select_related()` to include related models in our querysets.
|
2013-11-03 05:34:05 +08:00
|
|
|
|
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
class Country(models.Model):
|
2010-02-28 00:30:27 +08:00
|
|
|
name = models.CharField(max_length=50)
|
2009-05-11 18:10:03 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
class State(models.Model):
|
2010-02-28 00:30:27 +08:00
|
|
|
name = models.CharField(max_length=50)
|
2015-07-22 22:43:21 +08:00
|
|
|
country = models.ForeignKey(Country, models.CASCADE)
|
2009-05-11 18:10:03 +08:00
|
|
|
|
2012-08-12 18:32:08 +08:00
|
|
|
def __str__(self):
|
2010-02-28 00:30:27 +08:00
|
|
|
return self.name
|
2009-05-11 18:10:03 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
class StateProxy(State):
|
2010-02-28 00:30:27 +08:00
|
|
|
class Meta:
|
|
|
|
proxy = True
|
2009-05-11 18:10:03 +08:00
|
|
|
|
|
|
|
# Proxy models still works with filters (on related fields)
|
|
|
|
# and select_related, even when mixed with model inheritance
|
2013-11-03 05:34:05 +08:00
|
|
|
|
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
class BaseUser(models.Model):
|
|
|
|
name = models.CharField(max_length=255)
|
|
|
|
|
2013-08-15 15:32:54 +08:00
|
|
|
def __str__(self):
|
|
|
|
return ':'.join((self.__class__.__name__, self.name,))
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
class TrackerUser(BaseUser):
|
|
|
|
status = models.CharField(max_length=50)
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
class ProxyTrackerUser(TrackerUser):
|
|
|
|
class Meta:
|
|
|
|
proxy = True
|
|
|
|
|
|
|
|
|
|
|
|
class Issue(models.Model):
|
|
|
|
summary = models.CharField(max_length=255)
|
2015-10-02 02:57:58 +08:00
|
|
|
assignee = models.ForeignKey(ProxyTrackerUser, models.CASCADE, related_name='issues')
|
2009-05-11 18:10:03 +08:00
|
|
|
|
2012-08-12 18:32:08 +08:00
|
|
|
def __str__(self):
|
2013-08-15 15:32:54 +08:00
|
|
|
return ':'.join((self.__class__.__name__, self.summary,))
|
2009-05-11 18:10:03 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
class Bug(Issue):
|
|
|
|
version = models.CharField(max_length=50)
|
2015-07-22 22:43:21 +08:00
|
|
|
reporter = models.ForeignKey(BaseUser, models.CASCADE)
|
2009-05-11 18:10:03 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
class ProxyBug(Bug):
|
|
|
|
"""
|
|
|
|
Proxy of an inherited class
|
|
|
|
"""
|
|
|
|
class Meta:
|
|
|
|
proxy = True
|
|
|
|
|
|
|
|
|
|
|
|
class ProxyProxyBug(ProxyBug):
|
|
|
|
"""
|
|
|
|
A proxy of proxy model with related field
|
|
|
|
"""
|
|
|
|
class Meta:
|
|
|
|
proxy = True
|
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
class Improvement(Issue):
|
|
|
|
"""
|
|
|
|
A model that has relation to a proxy model
|
|
|
|
or to a proxy of proxy model
|
|
|
|
"""
|
|
|
|
version = models.CharField(max_length=50)
|
2015-07-22 22:43:21 +08:00
|
|
|
reporter = models.ForeignKey(ProxyTrackerUser, models.CASCADE)
|
|
|
|
associated_bug = models.ForeignKey(ProxyProxyBug, models.CASCADE)
|
2009-05-11 18:10:03 +08:00
|
|
|
|
2013-11-03 05:34:05 +08:00
|
|
|
|
2009-05-11 18:10:03 +08:00
|
|
|
class ProxyImprovement(Improvement):
|
|
|
|
class Meta:
|
2012-03-22 16:49:48 +08:00
|
|
|
proxy = True
|