【问题标题】:Return proxied class in many to many relation, Django 2.0在多对多关系中返回代理类,Django 2.0
【发布时间】:2019-04-27 02:11:59
【问题描述】:

从另一个安装的应用程序,我有这样的模型

class Organization(model.Model):
    name = models.CharField(max_length=255, blank=True)

class Person(model.Model):
    name = models.CharField(max_length=255, blank=True)

class Membership(model.Model):

    organization = models.ForeignKey(
        Organization,
        related_name='memberships',
        # memberships will go away if the org does
        on_delete=models.CASCADE,
        help_text="A link to the Organization in which the Person is a member.")

    person = models.ForeignKey(
        Person,
        related_name='memberships',
        null=True,
        # Membership will just unlink if the person goes away
        on_delete=models.SET_NULL,
        help_text="A link to the Person that is a member of the Organization.")

在我的应用程序中,我需要为某些模型添加一些方法。所以我有一个像

class ProxiedOrganization(other_app.models.Organization):
    class Meta:
        proxy = True

    special_attribute = 'foo'


class ProxiedPerson(other_app.models.Person):
    class Meta:
        proxy = True

    def special_method(self):
         print('I do something special')

当我从某个组织获得成员资格时,它们的类型是 other_app.models.Person

> type(proxied_org_instance.memberships[0].person)
<class 'other_app.models.Person'>

但是,我希望它们成为我的代理类的实例

> type(proxied_org_instance.memberships[0].person)
<class 'my_app.models.ProxiedPerson'>

有什么好的方法吗?这是我可以用查询管理器做的事情吗?该解决方案必须适用于 Django 2.0。

【问题讨论】:

标签: django django-models django-2.0


【解决方案1】:

您需要在OrganizationProxiedPerson 中添加一个ForeignKey。例如:

class MemberShip(models.Model):
    person = models.ForeignKey(
        ProxyPerson,
        related_name='memberships',
        null=True,
        # Membership will just unlink if the person goes away
        on_delete=models.SET_NULL,
        help_text="A link to the Person that is a member of the Organization.")

或者您可以通过以下方式获取代理人员实例:

proxy_person = ProxyPerson.objects.get(pk=proxied_org_instance.memberships[0].person.pk)

或者

proxy_persons = ProxyPerson.objects.filter(
                    pk__in = proxied_org_instance.memberships.all().values_list('person_id')
                )

根据documentation

MyPerson 类与其父类在同一个数据库表上运行 人物类。特别是,任何新的 Person 实例也将 通过 MyPerson 访问,反之亦然

表示您可以通过ProxyPerson Instance 访问Person Instance,反之亦然。

【讨论】:

  • 这很有帮助,但我希望将 proxied_org_instance.memberships 的行为更改为默认情况下,ProxiedPersons 在进行查询后不必将它们强制转换为 ProxiedPerson。跨度>
  • 嗯.. 但是,我想使用other_appMembership 表中的数据。也许我可以通过在 my_app 中创建一个非托管的 Membership 模型来做到这一点
【解决方案2】:

我改编了 Matt Schinckel 的 work on overriding proxy model relations,以获得适用于 Django 2.0 和 2.1 的解决方案。该代码以library on pypi 的形式提供。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    • 2013-06-12
    • 2021-01-28
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多