Django 管理内联表单 - 将外键查询集限制为一组值

发布于 2024-10-07 04:14:05 字数 1006 浏览 0 评论 0原文

我有一些相互关联的模型需要在单个管理页面上共存。想法是这样的:

戏剧作品有演员,演员有指定的角色。戏剧作品与给定的书面文本(戏剧、改编等)相关,并且书面文本包含该文本的所有角色的列表。添加作品时,每个演员都需要与这些角色之一关联。

数据模型的工作方式如下:

模型:Production、Person、CastMember、Role、WrittenText

关系:Production 和 Person 通过 CastMember 建立 M2M 关系,CastMember 添加一个“角色”字段 - 一个 Role 对象的外键。角色本身有一个指向 WrittenText 对象的外键。

所以,问题是这样的:在 Productions 的管理页面中,我有一个 TabularInline 来添加 CastMembers。表中的 CastMember 条目的“角色”字段应仅限于 Production 引用的 WrittenText 中指定的角色。

我通过覆盖模型表单来解决这个问题:

class CastMemberForm(ModelForm):
    class Meta:
        model = CastMember

    def __init__(self, *args, **kwargs):
        super(CastMemberForm, self).__init__(*args, **kwargs)
        if 'instance' in kwargs:
         self.fields['role'].queryset = Role.objects.filter(source_text=self.instance.production.source_text)

但是,只有当您从下拉列表中选择一个人,保存,然后选择角色时,这才有效 - 否则您只会得到所有角色的列表。取出“if 'instance' in kwargs”会给我一个DoesNotExistError。

如果没有客户端 JS 之类的东西,这是否太复杂了,或者是否有我缺少的更简单的解决方案?

I have some interrelated models that need to co-exist on a single admin page. Here's the idea:

Theater productions have cast members, and cast members have specified roles. A theater production is related to a given written text (play, adaptation, etc.), and the written text holds a list of all the roles for that text. When adding a Production, each cast member needs to be associated with one of those roles.

Here's how the data model is working:

Models: Production, Person, CastMember, Role, WrittenText

Relationships: Production and Person have an M2M relationship through CastMember, which adds a "role" field - a ForeignKey to a Role object. Role itself has a ForeignKey to a WrittenText object.

So, the problem is this: in the admin page for Productions, I have a TabularInline to add CastMembers. The CastMember entries in the table should have their 'role' field limited to only the roles specified in the WrittenText that the Production references.

I made a half-way solution to the problem by overriding the model form:

class CastMemberForm(ModelForm):
    class Meta:
        model = CastMember

    def __init__(self, *args, **kwargs):
        super(CastMemberForm, self).__init__(*args, **kwargs)
        if 'instance' in kwargs:
         self.fields['role'].queryset = Role.objects.filter(source_text=self.instance.production.source_text)

But, this only works if you choose a Person from the drop-down, save, and then choose the role - otherwise you just get a list of all roles. Taking out "if 'instance' in kwargs" gives me a DoesNotExistError.

Is this just way too complex to do without something like client-side JS, or is there a simpler solution that I'm missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清风无影 2024-10-14 04:14:05

这里是通过 javascript/ajax 链接选择框的示例。基本上应该是相同的原理,但是你应该需要调整js以不更新一个选择框,而是在内联管理中更新所有这些......也许这会给你一个小小的启发!

Here is an example of chained select boxes via javascript/ajax. It should basically be the same principle, but you should need to tweak the js to not update one select box, but all of them in the inline admin... Maybe this gives you a small inspiration!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文