1

我在 Django 中开发的模型有些复杂。基本思想是网站上的用户可以给人们奖励,但我也想跟踪用户和奖励获得者之间的关系。一个用户可以给同一个人多个奖励,但他们之间只有一种关系。模型看起来像这样(用户是标准的 auth_user 模型):

class Recipient(models.Model):
    name = models.CharField(max_length=255)
    senders = models.ManyToManyField(User, through='Relationship')

class Relationship(models.Model):
    user = models.ForeignKey(User)
    recipient = models.ForeignKey(Recipient)
    relationship = models.CharField(max_length=255, blank=True, default='')
    class Meta:
        unique_together = (('user', 'recipient'),)

class Award(models.Model):
    recipient = models.ForeignKey(Recipient)
    user = models.ForeignKey(User)
    relationship = models.ForeignKey(Relationship)
    award_name = models.CharField(max_length=255)

在管理员中我有类似的东西

class RelationshipInline(admin.StackedInline):
    model = Relationship

class AwardAdmin(admin.ModelAdmin):
    inlines = [RelationshipInline]
    exclude = ['relationship']

admin.site.register(Recipient)
admin.site.register(Award, AwardAdmin)

当我尝试在管理员中添加奖励时,我收到错误“<class 'Relationship'> has no ForeignKey to <class 'Award'>”。我意识到这是因为当我编辑 Award 时,Django 不知道应该内联编辑哪个关系,但事实上(对人类而言)很明显它是具有相同用户/收件人对的关系。我不能指定关系中的用户/收件人是一个键,因为 Django 不支持多列键(所以我所能做的就是将它们指定为 unique_together)。同样,我不能指定 Award 中的用户/收件人是关系的多列外键。

有什么办法可以得到我想要得到的东西吗?当 Award 与关系存在多对一关系时,必须在管理员中单独编辑关系似乎是一个巨大的不便。有没有更好的方法来组织模型?

4

1 回答 1

1

导致您描述的错误的基本问题是因为您不能在“奖励”中包含“关系”的内联,它应该反过来才能正常工作。这是有道理的,因为内联旨在提供一种创建任意数量的相关记录(在本例中为关系)绑定到您正在编辑的父记录(一个奖项)的方法,但奖项只能与一个关系相关,所以使用内联不起作用。

无论如何,我将建议进行一些简化...

我建议Recipient完全放弃模型并切换到这样的东西:

class Relationship(models.Model):
    user1 = models.ForeignKey(User)
    user2 = models.ForeignKey(User)
    relationship = models.CharField(max_length=255, blank=True, default='')
    class Meta:
        unique_together = (('user1', 'user2'),)

class Award(models.Model):
    recipient = models.ForeignKey(User)
    user = models.ForeignKey(User)
    relationship = models.ForeignKey(Relationship)
    award_name = models.CharField(max_length=255)

而且,我不会专门管理 Award 模型上的“关系”值,而是重写save()获取或创建 2 个用户的关系并保存它的方法。这看起来像这样(未经测试):

...
from django.db.models import Q
...
class Award(models.Model):
    ...
    def save(self, *args, **kwargs):
        try:
            # Query for an existing relationship between the 2 users in question...
            relationship = Relationship.objects.get(
                (Q(user1=self.recipient) & Q(user2=self.user)) | (Q(user1=self.user) & Q(user2=self.recipient))
            )
        except:
            relationship = Relationship.objects.create(user1=self.recipient, user2=self.user, relationship='Pals')
        self.relationship = relationship
        super(Award, self).save(*args, **kwargs)
于 2012-06-19T21:23:06.877 回答