如何扩展Django组模型?

时间:2021-03-27 07:24:29

Is there a way to extend the built-in Django Group object to add additional attributes similar to the way you can extend a user object? With a user object, you can do the following:

是否有一种方法可以扩展内置的Django组对象,以添加与扩展用户对象类似的其他属性?对于用户对象,您可以执行以下操作:

class UserProfile(models.Model):
    user = models.OneToOneField(User)

and add the following to the settings.py file

并添加以下设置。py文件

AUTH_PROFILE_MODULE = 'app.UserProfile'

which gets you:

这让你:

profile = User.objects.get(id=1).get_profile()

Is there any equivalent to this approach for extending a group? If not, is there an alternative approach I can take?

对于扩展一个组,是否有类似的方法?如果没有,我是否可以采取另一种方法?

2 个解决方案

#1


18  

You can create a model that subclasses Group, add your own fields, and use a Model Manager to return any custom querysets you need. Here's a truncated example showing how I extended Group to represent Families associated with a school:

您可以创建一个模型,该模型将子类分组、添加您自己的字段,并使用模型管理器返回您需要的任何自定义查询集。这里有一个截短的例子,展示了我如何扩展团队来代表与学校相关的家庭:

from django.contrib.auth.models import Group, User

class FamilyManager(models.Manager):
    """
    Lets us do querysets limited to families that have 
    currently enrolled students, e.g.:
        Family.has_students.all() 
    """
    def get_query_set(self):
        return super(FamilyManager, self).get_query_set().filter(student__enrolled=True).distinct()


class Family(Group):
    notes = models.TextField(blank=True)

    # Two managers for this model - the first is default 
    # (so all families appear in the admin).
    # The second is only invoked when we call 
    # Family.has_students.all()  
    objects = models.Manager()
    has_students = FamilyManager()

    class Meta:
        verbose_name_plural = "Families"
        ordering = ['name']

    def __unicode__(self):
        return self.name

#2


37  

If you simply subclass the Group object then by default it will create a new database table and the admin site won't pick up any new fields.

如果您只是对Group对象进行子类化,那么默认情况下,它将创建一个新的数据库表,管理站点不会接收任何新字段。

You need to inject new fields into the existing Group:

您需要向现有组注入新字段:

if not hasattr(Group, 'parent'):
    field = models.ForeignKey(Group, blank=True, null=True, related_name='children')
    field.contribute_to_class(Group, 'parent')

To add methods to the Group, subclass but tag the model as proxy:

要向组中添加方法,子类但将模型标记为代理:

class MyGroup(Group):

    class Meta:
        proxy = True

    def myFunction(self):
        return True

#1


18  

You can create a model that subclasses Group, add your own fields, and use a Model Manager to return any custom querysets you need. Here's a truncated example showing how I extended Group to represent Families associated with a school:

您可以创建一个模型,该模型将子类分组、添加您自己的字段,并使用模型管理器返回您需要的任何自定义查询集。这里有一个截短的例子,展示了我如何扩展团队来代表与学校相关的家庭:

from django.contrib.auth.models import Group, User

class FamilyManager(models.Manager):
    """
    Lets us do querysets limited to families that have 
    currently enrolled students, e.g.:
        Family.has_students.all() 
    """
    def get_query_set(self):
        return super(FamilyManager, self).get_query_set().filter(student__enrolled=True).distinct()


class Family(Group):
    notes = models.TextField(blank=True)

    # Two managers for this model - the first is default 
    # (so all families appear in the admin).
    # The second is only invoked when we call 
    # Family.has_students.all()  
    objects = models.Manager()
    has_students = FamilyManager()

    class Meta:
        verbose_name_plural = "Families"
        ordering = ['name']

    def __unicode__(self):
        return self.name

#2


37  

If you simply subclass the Group object then by default it will create a new database table and the admin site won't pick up any new fields.

如果您只是对Group对象进行子类化,那么默认情况下,它将创建一个新的数据库表,管理站点不会接收任何新字段。

You need to inject new fields into the existing Group:

您需要向现有组注入新字段:

if not hasattr(Group, 'parent'):
    field = models.ForeignKey(Group, blank=True, null=True, related_name='children')
    field.contribute_to_class(Group, 'parent')

To add methods to the Group, subclass but tag the model as proxy:

要向组中添加方法,子类但将模型标记为代理:

class MyGroup(Group):

    class Meta:
        proxy = True

    def myFunction(self):
        return True