Shelly Bysshe
Shelly Bysshe

Reputation: 13

Django Show all posts from a single user

I'm building an instagram-ish clone in Django. I have the basic functionality working, where a user can post an image, and this is displayed on the main page. I would like to make a 'user page' that only displays posts from a user. For example, example.com/foobar would only display posts from the user 'foobar'.

I believe i have the urls.py and template working correctly, but I can not figure out how to only iterate through items and pull out ones of a specific user. I realize this should be a queryset of some kind, but other than that I'm stumped. Should this be its own class, or could I extend the existing PostList class to pull out a single author's posts?

post_detail.html - gets all the images stored in the database, this works fine.

                    {% for post in object_list %}
                        <td><a href="{% url 'detail' pk=post.pk %}"><img src="{{ post.image.url }}" width="300"></a></td>
                        {% if forloop.counter|modulo:4 %}    
                        </tr><tr>
                        {% endif %}
                    {% endfor %}

profile.html - shows all posts from a user (as in example.com/foobar)

    <table>
        <tr>
        {% for post in object_list %}
            <td><a href="{% url 'detail' pk=post.pk %}"><img src="{{ post.image.url }}" width="300"></a></td>
            {% if forloop.counter|modulo:4 %}    
            </tr><tr>
            {% endif %}
        {% endfor %}
        </tr>
    </table>

urls.py - I believe this works correctly.

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', PostList.as_view(), name='list'),
    path('<str:username>/', Profile.as_view(), name='user_profile'),

views.py:

from posts.models import Post

class PostList(ListView):
    ordering = ['-created']
    paginate_by = 12
    model = Post

class Profile(ListView):
    template_name = 'posts/profile.html'
    UserName = self.kwargs.get("username")
    queryset = PostList.queryset
    
    .filter(author = UserName)
    return queryset

models.py:

class Post(models.Model):
    image = models.ImageField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

Upvotes: 1

Views: 530

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476594

You can override get_queryset():

class ProfileView(ListView):
    template_name = 'posts/profile.html'
    model = Post

    def get_queryset(self, **kwargs):
        return super().get_queryset(**kwargs).filter(
            author__username=self.kwargs['username']
        )

Note: In Django, class-based views (CBV) often have a …View suffix, to avoid a clash with the model names. Therefore you might consider renaming the view class to ProfileView, instead of Profile.

Upvotes: 1

Related Questions