Как связать стороннюю модель и представление с собственной моделью в Django

#python #django #django-models #django-queryset #django-generic-relations

Вопрос:

Я успешно внедрил django-contrib-комментарии в свой проект и начал шаг за шагом корректировать его, чтобы он на 100% соответствовал моему проекту. Теперь у меня есть следующая проблема, которую я не могу решить:

У меня есть модель Poller , которая предлагает два возможных голоса для любого пользователя, хранящегося в модели Vote . Теперь, если пользователь комментирует опрашиваемого, я хотел бы вернуть его индивидуальный голос за этого конкретного опрашиваемого в предоставленный комментарий в шаблоне.

Поскольку я ни в коем случае не хочу прикасаться к архитектуре 3-й стороны, я бы предпочел получить необходимый набор запросов, на мой взгляд.

Модель комментариев пакета django-contrib-комментарии

 class CommentAbstractModel(BaseCommentAbstractModel):

    user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('user'),
                
    [..]             
 

Мой опросник, Голосование и Модели учетной записи/пользователя

 class Poller(models.Model):
    poller_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created_on = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(Account, on_delete=models.CASCADE)
[..]

class Vote(models.Model):
    poller = models.ForeignKey(Poller, on_delete=models.CASCADE, related_name='vote')
    user = models.ForeignKey(Account, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)
    poller_choice_one_vote = models.BooleanField(default=False)
    poller_choice_two_vote = models.BooleanField(default=False)
[..]

class Account(AbstractBaseUser):

    username = models.CharField(max_length=40, unique=True)
[..]
 

Короче говоря, как я могу получить доступ к Модели голосования для каждого пользователя, опубликовавшего комментарий, чтобы определить, какой голос он выбрал? Может быть, путем подкласса CommentAbstractModel и добавления внешнего ключа в Vote модель?

 @require_GET
def single_poller(request, poller_id):
    """
    renders a specific poller with prepopulated meta according to previous
    user interaction, e.g. votes and likes
    """

    # Retrieve the item via get
    poller = Poller.objects.get(poller_id=poller_id)
    
    [..] # how to go on here?
 

Ответ №1:

Вы можете определить a GenericRelation в Poller модели, чтобы получить все комментарии к определенному опросу. С помощью этого мы сможем получить доступ к пользователям и фильтровать голоса на основе этого:

 from django.contrib.contenttypes.fields import GenericRelation


class Poller(models.Model):
    ...
    comments = GenericRelation(MyCommentModel) # Change MyCommentModel to the comment model you used

poller = Poller.objects.get(poller_id=poller_id)

votes = Vote.objects.filter(
    poller=poller,
    user__in=poller.comments.all().values('user')
)
 

Редактировать:

Похоже, в комментариях django используется другое имя для поля object_id. Чтобы исправить это, нам нужно добавить object_id_field и установить его object_pk в GenericRelation ( object_pk это то, что django-comments , кажется, используется, не нужно переносить при добавлении этого):

 class Poller(models.Model):
    comments = GenericRelation(
        Comment,
        object_id_field='object_pk', # <-- Add this
    )
 

Комментарии:

1. Спасибо за ваш ответ, @BrianD. Как бы я тогда отображал все комментарии, связанные с этим опросником, включая голосование каждого создателя комментария за этого опрашиваемого в шаблоне?

2. Да, попробовал и получил ту же ошибку. Обновил свой ответ исправлением 🙂