【问题标题】:Django Generic Relations with Django AdminDjango 与 Django Admin 的通用关系
【发布时间】:2011-01-06 15:55:03
【问题描述】:

我有一个 Django 项目,它有一个“地址”模型。这用于多个地方 - “用户档案”模型、“医院”模型、“机构”模型等。

我正在使用 Django 的通用关系来允许这些对象中的每一个创建地址的外键。

但是,这似乎在 Django Admin 中引起了一些奇怪(或者我可能没有正确理解它的用途)。在 Django Admin 中,如果我尝试创建地址,我会看到“内容类型”和“对象 ID”的字段。如果未填写,模型将不会验证/保存。不知道该放什么。

问题是,我希望能够创建独立的 Address 对象。然后,当我创建用户配置文件或医院时,我可以将它们链接到 Address 对象,包括多个链接到同一个 Address 对象的可能性。

我应该如何使用具有泛型关系的 Django 管理员?

另外,我还打算使用 django-reversion 对模型进行版本控制,不确定这是否会导致通用关系和管理员出现任何问题?

干杯, 维克多

编辑:我应该补充一下,这是我之前发布的地址和内联问题:

Django - Designing Model Relationships - Admin interface and Inline

根据那里给出的答案,这就是地址模型是具有外键的模型的原因。而且由于普通的 FK 字段只能指向一种类型的对象,这就是我们使用泛型关系的原因。

每个用户/部门/医院等可能(并且在大多数情况下)有多个地址。

同一个地址可以被多个实体使用,但这种情况比较少见,我猜这里可以重复,对吧?

所以它是从用户/部门/医院到地址的一对多。

在最初的问题中,他们还建议使用抽象类,并为每个需要地址的实体使用不同的地址模型。我仍然不确定这是否是更好的方法,或者是否有办法让 GenericRelations 与我在这里尝试做的事情一起工作。

【问题讨论】:

    标签: django django-models generic-relationship


    【解决方案1】:

    在 django 中使用泛型关系正是如此。 ForeignKey 表示 ContentType (content_type),IntegerField 表示实例 ID (object_id)。如果您不知道ForeignKey 指向的内容类型,这些功能很有用。由于您知道您的目标是 Address 模型,因此您希望使用常规 ForeignKey(Address) 而不是泛型关系。

    回应您的评论

    实际上ForeignKey 更容易使用,因为您不需要通过 ContentType。

    class Address(models.Model):
      street=models.CharField(max_length=100)
      city=models.CharField(max_length=100)
    
    
    class Hospital(models.Model):
      name=models.CharField(max_length=100)
      created=models.DateTimeField()
      address=models.ForeignKey(Address, related_name="hospitals")
    
    class Institution(models.Model):
      name=models.CharField(max_length=100)
      address=models.ForeignKey(Address, related_name="institutions")
    
    
    >>> instance=Institution.objects.get(id=1)
    >>> instance.address.city
    >>> address=Address.objects.get(id=1)
    >>> address.institutions.all() 
    >>> address.hospitals.all()
    

    您的模型会共享地址吗?即HospitalInstitution 以及UserProfile 都可以指向同一个地址实例吗?还是每个人都有自己的地址?我试图理解为什么你创建了一个单独的类Address。如果要避免在每个类中重新输入相同的字段,您可以使用抽象模型类并将其子类化。或者您可能需要一个OneToOneField,它是两个实例之间的双向指针。

    【讨论】:

    • 嘿嘿,嗯,我认为从设计的角度来看,您应该将 FK 字段放在 Address 对象上,并将该链接指向需要地址的每个事物(用户、医院、机构等)。但是,由于您需要为此指定一个类型,这就是我使用泛型关系的原因。但是,如果我将 FK 字段放在另一个对象上,这不会破坏设计,或者使 ORM 变得奇怪吗?干杯,维克多
    • @victorhool 我认为@czarchaic 是正确的,对于您的描述,解决这种情况的最佳方法是`models.ForeignKey(Address),不会破坏设计也不会奇怪ORM,无论如何,如果你坚持使用泛型关系,阅读docs.djangoproject.com/en/1.1/ref/contrib/contenttypes/…中的文档
    • FK 的放置位置取决于哪一侧是“多”。用户/医院/机构可以有多个地址吗?然后 FK 应该在地址上,指向用户/医院/机构。但是,如果单个地址可以属于多个其他事物,那么您希望“其他事物”上的 FK 指向地址。
    • @Carl Meyer 是的,要求之一是每个通用对象(UserProfile、医院、机构等)有多个地址。此外,这些地址可以共享。
    • @victorhooi 如果每个对象需要多个地址,每个地址需要多个对象(共享地址)而不重复地址,那么无论哪种方式都不需要 FK,你需要一个多对多。而且没有 GenericManyToMany,尽管您可以通过手动创建中间模型来伪造一个。
    猜你喜欢
    • 2015-04-03
    • 2011-08-07
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 2012-10-20
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多