我在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'Adisgence'>没有ForeignKey到< class'Accept'>”。我意识到这是因为当我编辑Award时,Django不知道应该内联编辑哪个关系,但事实上(对人类而言)它是具有相同用户/收件人对的那个。我不能指定Relationship中的用户/收件人是一个键,因为Django不支持多列键(所以我所能做的就是将它们指定为unique_together)。同样,我无法指定Award中的用户/收件人是关系的多列外键。
有没有办法得到我想要的东西?当与奖励中的多对一关系时,必须在管理员中单独编辑关系似乎是一个巨大的不便。有没有更好的方法来组织模型?
答案 0 :(得分: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模型中的'relationship'值,而是覆盖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)