1

I am trying to add an Item to a list view, the UserPost list view has already a Post context.

In my project, a user can add a post and add an item each is a different app with different models.

So In my UserPost list view, I have my Posts looped related to a specific user related to it.

What I am trying to do is check if this post.user has an item filtered by the same user and if it does exist a button show appears in the page linking to another page with this list of items related to this user. To be more descriptive I want to check for Item for the designer__post and link to this page which is {% url 'core:designer-posts' item.designer %}

I hope this clears my question if there are any more clarifications required or code please let me know to add it.

I tried to use make use of an Exists subquery [Django-doc] but I didn't succeed it perfecting it

Here is the models.py

class Post(models.Model):
    designer = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)

Here is the views.py

class UserPostListView(ListView):
    model = Post
    template_name = "user_posts.html"
    context_object_name = 'posts'
    queryset = Post.objects.filter(admin_approved=True)
    paginate_by = 6

    def get_queryset(self):
        user = get_object_or_404(User, username=self.kwargs.get('username'))
        return Post.objects.filter(designer=user, admin_approved=True).order_by('-date_posted')

Here is the template user_posts.html

{% if item %}
 <a class="primary btn-lg" href="{% url 'core:designer-posts' item.designer %}" role="button">Go to items</a>
{% else %}
  <a href="{% url 'core:designer-posts' item.designer %}">
    <button type="button" class="btn btn-primary btn-lg btn-block">Go to items</button>
  </a>   
{% endif %}

here is the item models.py

class Item(models.Model):
    designer = models.ForeignKey(
        User, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)

here is the designerlist views.py that I am trying to link to from the user post view if it is available

class DesignerPostListView(ListView):
    model = Item
    template_name = "designer_posts.html"
    context_object_name = 'items'
    paginate_by = 6

    def get_queryset(self):
        user = get_object_or_404(User, username=self.kwargs.get('username'))
        return Item.objects.filter(designer=user).order_by('-timestamp')

Here are the views related to the post model

app_name = 'score'

urlpatterns = [
    path('', PostListView.as_view(), name='score'),
    path('user/<str:username>', UserPostListView.as_view(), name='user-posts'),
]

Here are the views related to the item model

app_name = 'core'

urlpatterns = [
    path('', HomeView.as_view(), name='home'),
    path('user/<str:username>', DesignerPostListView.as_view(),
         name='designer-posts'),
]

Projects URLs

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('allauth.urls')),
    path('', include('core.urls', namespace='core')),
    path('score/', include('score.urls', namespace='score')),
    path('register/', user_views.register, name='register'),

]

enter image description here

A_K
  • 731
  • 3
  • 15
  • 40
  • 1
    "if this post.user has an item filtered by the same user and if it does exist a button show appears in the page linking to another page with this list of items related to this user." All I get is that you want to add a button, but can you please explain the precondition more clearly? – crimsonpython24 Jul 29 '20 at 05:37
  • @crimsonpython24 I have added a more descriptive image I hope it helps – A_K Jul 29 '20 at 22:39
  • How is a Post related to an Item? Can you share a mockup with hypothetical data in the database? – aaron Jul 31 '20 at 00:46
  • @aaron The item and post are 2 different models in 2 separate apps. For example, a user can upload a post (consider it as an article) only, or he might have an item (consider it as a product) only, or he could have both and item and a post under his name. For each user, I have created 2 list views one for items and one for posts and I want to link each together by a button for easier navigation between these 2 pages. Does it make sense? – A_K Jul 31 '20 at 01:09
  • so basically the item is not bound by any post it is bound by perticular user so that means you need to show all the item for a perticular user in a post right – Kishan Parmar Jul 31 '20 at 01:12
  • @KishanParmar correct, because when I am in `UserPostListView` I am seeing posts of User X who might have items under his name to be viewed in `DesignerPostListView` for the same User X, I want to link these 2 views together – A_K Jul 31 '20 at 01:17
  • @A_K from you problem you have to make a item related to post so if you put relation in item to the post as foreignkey it will already as related to user and a post – Kishan Parmar Jul 31 '20 at 01:18
  • user_posts.html shows a (differently built) button regardless of `item`? I suppose the `item` in `{% if item %}` is a placeholder? – aaron Jul 31 '20 at 01:20
  • does the *"specific user"* is identified by the ***authentication***? I mean, are you trying to filter the `UserPostListView` and `DesignerPostListView` with ***logged-in user***? – JPG Jul 31 '20 at 03:40
  • @ArakkalAbu no it is not the currently logged in user it is a user requested from the home page – A_K Jul 31 '20 at 03:45
  • Can you add the URLs of the views? – JPG Jul 31 '20 at 03:49
  • @ArakkalAbu I added the URLs – A_K Jul 31 '20 at 03:55
  • 1
    Can you also add the ***root URL config***? because it seems your both "relevant views" are pointing towards the same URL – JPG Jul 31 '20 at 03:58
  • I added the URL of the project is this the root URL config you meant? – A_K Jul 31 '20 at 04:02

2 Answers2

1

First, you need to pass one context variable by overriding the get_context_data(...) method, that decides whether the user has Items or not

class UserPostListView(ListView):
    # rest of your code
    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        has_items = Item.objects.filter(designer__username=self.kwargs['username']).exists()
        context['has_items'] = has_items
        return context

Then in your template, use this has_items variable by,

{% if has_items %}
    <a class="primary btn-lg" href="{% url 'core:designer-posts' username=view.kwargs.username %}" role="button">Go to items</a>
{% endif %}

Also, you were not passing the username to the url tag, it should be

{% url 'core:designer-posts' username=view.kwargs.username %}

here, I used view.kwargs.username to get the username from the URL

References

  1. ListView.get_context_data(...)
  2. url tag with kwargs
JPG
  • 82,442
  • 19
  • 127
  • 206
0

in {% url %} item.designer passes a user object you have to provide id for that like this

 <a href="{% url 'core:designer-posts' item.designer.id %}">
Kishan Parmar
  • 819
  • 6
  • 8