Как показать сообщения с помощью DetailView на Django
У меня есть модель Message и модель Post.
Я хочу показать все сообщения, которые были опубликованы в одном посте.
Не могу придумать, как получить все сообщения на определенном посту, используя класс DetailView.
Как я могу это сделать? Или я должен создать другой класс ListView для сообщений?
models.py
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User,on_delete=models.CASCADE)
topic = models.ForeignKey(Topic,on_delete=models.SET_NULL,null=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail',kwargs={'pk':self.pk})
class Message(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE)
post = models.ForeignKey(Post,on_delete=models.CASCADE)
body = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.body[0:50]
views.py
class PostDetailView(DetailView):
model = Post
В шаблоне вы можете представить это как:
{% for message in object.message_set.all %}
{{ message.body }}
{% endfor %}
Таким образом, для объекта Post в контексте с именем object будут извлечены все связанные с ним Messages.
Если вы хотите получить данные и связанного пользователя, вы можете работать с объектом Prefetch [Django-doc]:
from django.db.models import Prefetch
class PostDetailView(DetailView):
model = Post
queryset = Post.objects.prefetch_related(
Prefetch('message_set', Message.objects.select_related('user'))
)
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL[Django-doc] to refer to the user model, than to use theUsermodel [Django-doc] directly. For more information you can see the referencing theUsermodel section of the documentation.
Note: Django's
DateTimeField[Django-doc] has aauto_now_add=…parameter [Django-doc] to work with timestamps. This will automatically assign the current datetime when creating the object, and mark it as non-editable (editable=False), such that it does not appear inModelForms by default.