Django - Предоставление представлениям доступа к нескольким моделям
Я следовал учебнику на Youtube, который делает сайт для создания постов. В настоящее время я работаю над отображением профилей других людей и их постов на страницах их профилей. Я сделал это, обратившись к автору первого сообщения, но это работает только в том случае, если пользователь что-то опубликовал. Есть ли другой способ сделать это?
Вид:
class UserProfileView(ListView):
model = Post
template_name = 'blog/user_profile.html' # defaults to <app>/<model>_<viewtype>.html--> blog/post_list.html
context_object_name = 'posts' #defaults to objectlist
paginate_by = 5
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get('username'))
return Post.objects.filter(author=user).order_by('-date_posted')
user_profile.html:
{% extends 'blog/base.html' %}
{% block title %}{{ view.kwargs.username }}'s Profile{% endblock title %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="{{ posts.first.author.profile.image.url }}">
<div class="media-body">
<h2 class="account-heading">{{ view.kwargs.username }}</h2>
<p class="text-secondary">{{ posts.first.author.email }}</p>
<p class="article-content">{{ posts.first.author.profile.bio }}</p>
</div>
</div>
{% if posts.first.author == user %}
<a class="btn btn-outline-secondary ml-2" href="{% url 'change_profile' %}">Edit Profile</a>
{% endif %}
</div>
<br>
{% if posts.first.author == user %}
<h3 class="ml-2 article-title">Blogs You Posted</h3>
{% else %}
<h3 class="ml-2 article-title">Blogs By {{ view.kwargs.username }}</h3>
{% endif %}
И модуль Post и Profile:
class Post(models.Model):
title = models.CharField(max_length=50)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self) -> str:
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk':self.pk})
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
bio = models.CharField(max_length=225, blank=True, default='')
def __str__(self) -> str:
return f"{self.user.username}'s Profile"
def save(self, *args, **kwargs):
super(Profile, self).save(*args, **kwargs)
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
img.thumbnail((300,300))
img.save(self.image.path)
Во-первых, вам, вероятно, не нужно .first
в вашем template
, потому что вы используете первый элемент из QuerySet
. Если вы обращаетесь к User profile
, вы можете использовать DetailView
. Кроме того, вы можете попробовать с другой страницы и предоставить filtered posts
в context
. Например, что-то вроде этого.
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['posts'] = Post.objects.filter(author=user) # from kwargs
return context
#template
<ul>
{% for post in posts %}
<li>{{ post.title }}</li>
<li>{{ post.content }}</li>
<li>{{ post.date_posted }}</li>
{% endfor %}
</ul>
PS С уважением Кори.