Heisenberg
Heisenberg

Reputation: 495

Django: How to use more than 2 Class Based Generic Views in one template

I was trying to create a web app in which a user can see other posts while updating a post. So, for that, I want to use both ListView And UpdateView together in the same template.

My Views.py:

from django.shortcuts import render
from .models import Entry
from django.views.generic import ListView
from django.views.generic.edit import UpdateView
from django.contrib.auth.models import User
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin


class index(LoginRequiredMixin, ListView):
    template_name = 'diary/index.html'
    context_object_name = 'entries'

    def get_queryset(self):  # def get_queryset(self, request):
        return Entry.objects.filter(author=self.request.user)


class EntryUpdate(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = Entry
    fields = ['title', 'content']

    template_name = 'diary/update.html'

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)

    def test_func(self):
        post = self.get_object()
        if self.request.user == post.author:
            return True
        else:
            return False

I don't know if I should create another view, or that there is an inbuilt functionality for this, so, it would be really helpful if you guys can help me out.

Any Help Would Be Appreciated!

EDIT:

My ListView Code In views.py:

class index(LoginRequiredMixin, ListView):
    template_name = 'diary/index.html'
    context_object_name = 'entries'

    def get_queryset(self):
        return Entry.objects.filter(author=self.request.user)

My UpdateView in views.py:

class EntryUpdate(LoginRequiredMixin, MultipleObjectMixin,UserPassesTestMixin, UpdateView):
    model = Entry
    fields = ['title', 'content']
    template_name = 'diary/update.html'

    def get_queryset(self):
        return Entry.objects.filter(author=self.request.user)

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)

    def test_func(self):
        post = self.get_object()
        if self.request.user == post.author:
            return True
        else:
            return False

The Error, I'm getting:

'EntryUpdate' object has no attribute 'object_list'

Upvotes: 1

Views: 382

Answers (1)

Pumi
Pumi

Reputation: 133

You could perhaps try a MultipleObjectMixin in your UpdateView.

You can define with this mixin get_queryset() and access object_list in the template. Check out the documentation for more info

EDIT

Sure, here's a short code example:

# demo/models.py

from django.db import models

class Title(models.Model):
    title = models.CharField(max_length=100)
# demo/views.py

from django.views.generic import UpdateView
from django.views.generic.list import MultipleObjectMixin
from demo.models import Title


class UpdateWithListView(UpdateView, MultipleObjectMixin):
    model = Title
    template_name_suffix = '_update_form_with_list'
    fields = ['title']
    object_list = Title.objects.all()

update_with_list_view = UpdateWithListView.as_view()
# my_project/urls.py

from django.contrib import admin
from django.urls import path
from demo.views import update_with_list_view

urlpatterns = [
    path('<int:pk>', update_with_list_view),
    path('admin/', admin.site.urls),
]

And the template:

demo/templates/demo/title_update_form_with_list.html


Current title: {{ object.title }}

<form method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Update">
</form>

<p>All other titles:</p>

{% for title in object_list %}
<p>Title:  {{ title.title }}</p>
{% endfor %}

And this is what I got in the template (I had 10 "titles" in my DB, each with random character):

UpdateView with MultipleObjectMixin

EDIT 2 Regarding your edited question, you are missing the definition of "object_list" in your view, which is required by the MultipleObjectMixin.

Please note that in my code example, in views.py, I'm defining the object_list with the query that would populate the object_list. I believe that the error you receive is because the mixin is expecting to receive the object_list.

Please try adding:


# demo/views.py

# omitted imports


class UpdateWithListView(UpdateView, MultipleObjectMixin):
    model = Title
    template_name_suffix = '_update_form_with_list'
    fields = ['title']
    object_list = Title.objects.all() # make sure to define this with your query

update_with_list_view = UpdateWithListView.as_view()

If I'm not mistaken, the get_queryset() method is taking care of the object retrieval for the UpdateView, while object_list is relevant for the ListView.

Please try to add the object_list to your view and check if it solves the issue.

Upvotes: 1

Related Questions