我正在编写一个需要将数据与用户对关联的应用程序。例如,每个用户对都会有一个与之相关的兼容性分数,以及他们共同拥有的艺术家等多对多关系。我对执行此操作的最佳方法感到困惑,似乎我会使用以下组合:1)通过一对一关系扩展 User,2)在 User 表上使用与 self 的递归关系,3)耦合在 M2M 关系上指定额外的字段,但我无法理解模型的外观。
这就是我目前完成此操作的方式,我认为这不是最好的方法,因为它需要为每个查询两次通过数据库:
在 models.py (伪代码,假设有一个 Artist 类):
class UserProfile(models.Model):
user = models.OneToOneField(User)
zipcode = models.CharField(max_length=16)
def create_user_profile(sender, instance, created, **kwargs):
if created:
profile, created = UserProfile.objects.get_or_create(user=instance)
post_save.connect(create_user_profile, sender=User)
class Score(models.Model):
user = models.ForeignKey(User, related_name='score_first_user')
second_user = models.ForeignKey(User, related_name='score_second_user')
dh_score = models.DecimalField(decimal_places=2, max_digits=5)
cre_date = models.DateTimeField(auto_now_add=True)
upd_date = models.DateTimeField(auto_now=True)
deleted = models.BooleanField()
class Meta:
unique_together = ('user', 'second_user')
class UserArtist(models.Model):
user = models.ForeignKey(User, related_name='userartist_first_user')
second_user = models.ForeignKey(User, related_name='userartist_second_user')
artist = models.ForeignKey(Artist)
cre_date = models.DateTimeField(auto_now_add=True)
upd_date = models.DateTimeField(auto_now=True)
deleted = models.BooleanField()
然后在views.py中我使用类似(伪代码)的东西保存分数和普通艺术家:
s = Score(user=u, second_user=second_user score=dh_score)
s.save()
并使用以下方法检索它们:
u = User.objects.get(username="%s" % username)
user_scores = Score.objects.filter( Q(user=u.id) | Q(second_user=u.id) ).order_by('-dh_score')[:10]
for user_score in user_scores:
# non-relevant logic to determine who is user and who is partner
...
partner_artists = UserArtist.objects.filter( (Q(user=u.id) & Q(second_user=partner.id))\
| (Q(user=partner.id) & Q(second_user=u.id))
)
实现这一目标的最佳方法是什么?