Я пишу приложение, в котором мне нужно связать данные с парами пользователей. Например, каждая пара пользователей будет иметь оценку совместимости, связанную с ними, а также отношения «многие ко многим», такие как художники, которые у них общие. Меня смущает лучший способ сделать это, кажется, что я бы использовал комбинацию: 1) расширение User посредством отношения один-к-одному, 2) использование рекурсивного отношения к себе в таблице User, 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))
)
Каков наилучший способ сделать это?