基于 django 中另一个字段的唯一值字段

发布于 2024-07-28 21:55:35 字数 1103 浏览 3 评论 0原文

前言:我是 django 和数据库设计的新手。

超级编辑:我做了一些重大更改,因此更改之前的答案可能会引用此处不存在的内容。 我道歉。

我将直接使用代码: models.py:Word

class Player(models.Model):
    name = models.CharField()

class Team(models.Model):
    name = models.CharField()
    members = models.ManyToManyField(Player, through='Membership')

class Word(models.Model):
    word = models.CharField(unique=True)
    definition = models.CharField()
    ...

class Ownership(models.Model):
    owner = models.ForeignKey(Player)
    team = models.ForeignKey(Team)
    word = models.ForeignKey(Word)

class Membership(models.Model):
    team = models.ForeignKey(Team)
    player = models.ForeignKey(Player)

表已填充。 在管理中我创建了一个播放器。 然后我创建一个团队并向其中添加成员。 我已将所有权添加到管理员。 我创建了一个新的所有权,我可以从球员、球队和言语中进行选择。 我想设置一个限制,如果一个玩家拥有给定团队的一个单词,那么属于该团队的玩家不能在团队内拥有该单词。 他们可能在其他团队中拥有话语权。

现在就是这样。 我可以让同一支球队的两名不同球员拥有同一个词。 坏的。 基本上,我希望管理员说获取该团队内拥有的所有单词,而不是在下拉列表中提供它们。

我该如何建模这种关系? 如何在管理员中获得此功能?

编辑:我添加会员模型只是为了表明我正在尝试解决不同的问题。 正如我所说,这是我真正正在处理的事情的一个简化示例。 正如你所看到的,我已经完成了成员关系,我正在尝试解决一个单独的所有权问题。

Preface: I am new to django and to db design.

SUPEREDIT: I made some significant changes, so the answers before my changes may reference things not here. I apologize.

I'll get right to the code:
models.py:

class Player(models.Model):
    name = models.CharField()

class Team(models.Model):
    name = models.CharField()
    members = models.ManyToManyField(Player, through='Membership')

class Word(models.Model):
    word = models.CharField(unique=True)
    definition = models.CharField()
    ...

class Ownership(models.Model):
    owner = models.ForeignKey(Player)
    team = models.ForeignKey(Team)
    word = models.ForeignKey(Word)

class Membership(models.Model):
    team = models.ForeignKey(Team)
    player = models.ForeignKey(Player)

the Word table has been populated.
In the admin I create a Player. I then create a team and add members to it. I've added Ownership to the admin. I create a new Ownership and I get to pick from players, from the teams, and from the words. I'd like to put a constraint where if a player owns a word for a given team, then players belonging to that team can not own the word within the team. They may own the word in other teams.

The way it is now. I could have two different players on the same team own the same word. Bad. Basically I want the admin to say take all of the words owned within this team and not make them available in the drop down.

How can I model this relationship? How can I get this functionality in the admin?

EDIT: I added the membership model just to show that I am trying to solve a different problem. And as I said, this is a simplified example of what I am really working with. As you can see I've got the membership relationship done, I am trying to solve a separate problem of ownership.

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

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

发布评论

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

评论(1

北凤男飞 2024-08-04 21:55:36

您的架构不正确。 您应该使用“多对多关系上的额外字段”如 Django 文档中所示

它也在这里突出显示。

查看 unique_together您的“团队编号”关联。 我不确定它是否也可以与多对多方法中的额外字段结合使用。 否则,您可以强制视图中的唯一性,但我确实相信 unique_together 应该适合您的情况。

对于 1-99 的限制,您应该将其包含在表单验证中,并且与唯一性检查结合使用,您不需要整个表来存储数字 1-99。

更新您的编辑

我不确定您是否真的阅读了我的帖子或点击了我的任何链接,但它完全解决了您所描述的问题,除非您当然还没有正确解释问题。 数字的“所有权”不是您应该建模的东西,您应该在它所属的地方表达它:

class Player(models.Model):
    name = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name

class Team(models.Model):
    name = models.CharField(max_length=128)
    players = models.ManyToManyField(Player, through='Membership')

    def __unicode__(self):
        return self.name

class Membership(models.Model):
    player = models.ForeignKey(Player)
    team = models.ForeignKey(Team)
    number = models.IntegerField()
    """ ... """

    class Meta:
        unique_together = ('team', 'number')

所以请再次向我解释您如何需要玩家-团队-编号关联的所有权模型,因为我不确定什么确切地说,您想要实现的目标与我已经为您提供的目标是分开的。

Your schema is incorrect. You should be making use of "Extra fields on Many-to-Many relationships" as seen here in the Django docs.

It is also highlighted here on SO.

Look into unique_together for your "team-number" association. I'm not sure if it will also work in conjunction with the extra fields on the many-to-many approach. Otherwise, you could enforce the uniqueness in the view, but I do believe unique_together should work in your case.

For the 1-99 limitation, you should just include this in your form validation, and in conjunction with a uniqueness check, you do not need an entire table just to store the numbers 1-99.

Update for your edit

I'm not sure you actually read my post or followed any of my links but it solves exactly the problem you described, unless of course you still haven't explained the problem correctly. "Ownership" of a number is not something you should be modeling, you should be expressing it where it belongs:

class Player(models.Model):
    name = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name

class Team(models.Model):
    name = models.CharField(max_length=128)
    players = models.ManyToManyField(Player, through='Membership')

    def __unicode__(self):
        return self.name

class Membership(models.Model):
    player = models.ForeignKey(Player)
    team = models.ForeignKey(Team)
    number = models.IntegerField()
    """ ... """

    class Meta:
        unique_together = ('team', 'number')

So please explain to me again how you need an Ownership model for Player-Team-Number associations, because I'm not sure what exactly you're trying to achieve that is separate from what I already provided you.

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