Django - 设计模型关系 - 管理界面和内联 [英] Django - Designing Model Relationships - Admin interface and Inline

查看:850
本文介绍了Django - 设计模型关系 - 管理界面和内联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为我对Django的FK和管理员的理解是有点错误,所以我将重点关于如何建模下面情况的任何输入。

I think my understanding of Django's FK and admin is a bit faulty, so I'd value any input on how to model the below case.

首先,我们有通用地址对象。然后,我们有User's,每个都有一个UserProfile。通过这个,用户属于部门,以及有地址。

Firstly, we have generic Address objects. Then, we have User's, who each have a UserProfile. Through this, Users belong to departments, as well as having addresses.

部门本身也可以有多个地址,以及部门的头。所以它可能是这样的东西(这是我只是砍了现在的东西):

Departments themselves can also have multiple addresses, as well as a head of department. So it might be something like (this is something I'm just hacking up now):

class Address(models.Model):
    street_address = models.CharField(max_length=20)
    etc...

class Department(models.Model):
    name = models.CharField(max_lenght=20)
    head_of_department = models.OneToOneField(User)
    address = models.ForeignKey(Address)

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    address = models.ForeignKey(Address)
    department = models.OneToOneField(Department)

无论如何,首先,正确的方式是建立关系?

Anyhow, firstly, is that the right way of setting up the relationships?

其次,我想以显示在管理员中,您可以编辑部门,并且在该页面上,它将具有所有地址的内联列表,以便也可以编辑。我试过设置一个AddressInline类,并附加它作为内联到Department。

And secondly, I'd like it to appear in the admin that you can edit a department, and on that page, it'd have an inline list of all the addresses to also edit. I've tried setting up an AddressInline class, and attaching it as an inline to Department.

class AddressInline(admin.TabularInline):
    model = Address

class DepartmentAdmin(admin.ModelAdmin):
    inlines = [AddressInline]

但是,当我尝试显示它时,我会得到:

However, when I try to display that, I get:

Exception at /admin/people/department/1/
<class 'people.models.Address'> has no ForeignKey to <class 'people.models.Department'>

干杯,
Victor

Cheers, Victor

推荐答案

由于似乎你想要一个UserProfile或部门可能有很多地址,你的ForeignKeys是向后的。单个ForeignKey只能指向一个模型实例,而对指向单个模型实例的ForeignKeys的数量没有限制。所以你的ForeignKey应该在地址(在这种情况下你的内联将工作原样)。

Since it seems you want a UserProfile or Department to have potentially many addresses, your ForeignKeys are backward. A single ForeignKey can only point to one model instance, whereas there is no limit on the number of ForeignKeys that can point to a single model instance. So your ForeignKey should be on Address (in which case your inline would work as-is).

复杂的因素是,你有一个单一的地址模型,与其他两个模型相关;单个ForeignKey on Address不能指向UserProfile和Department。一个解决方案是有两个地址模型(DepartmentAddress,带有ForeignKey的部门和UserAddress,一个ForeignKey到UserProfile)。您可以通过让这两个代码继承自抽象基类,它包含所有的数据字段,但是你的数据库中仍然有两个大致相同的表。

The complicating factor is that you have a single Address model and you want to relate it to two other models; a single ForeignKey on Address can't point to both UserProfile and Department. One solution is to have two address models (DepartmentAddress, with a ForeignKey to Department, and UserAddress, with a ForeignKey to UserProfile). You could reduce duplication in your code by having these both inherit from an abstract base class containing all the data fields, but you still end up with two mostly-identical tables in your database.

另一个选项是在地址上拥有 GenericForeignKey ,可以指向任何模型的实例。您的内联需要成为 GenericInlineModelAdmin 。这违反了纯数据库规范化,不允许您的数据库进行正确的完整性检查。如果你今后可能有更多的模型,也会有地址,我会考虑这个;如果它可能只限于现在的两个,我可以去用上面的选项。

The other option is to have a GenericForeignKey on Address, which can point to an instance of any model. Your inline would then need to become a GenericInlineModelAdmin. This violates pure database normalization and doesn't allow your database to do proper integrity checking. If you had potentially more models in the future that would also have addresses, I'd consider this; if it's likely to be limited to only the current two, I might go with the above option instead.

这篇关于Django - 设计模型关系 - 管理界面和内联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆