francosy
francosy

Reputation: 153

Django - combine DetailView and ListView

I am new to Django and I want to build a web app that shows you a list of your events. You can have several different lists (like for sport events, birthdays...). I have made two models - Calendar (list of events) and Event.

On my page I have nav menu, where you can see a list of your "calendars". When you click on one calendar you can see a list of events for that calendar, but also I want to keep a list of calendars in the side bar.

As I understand Django I need two views for that - ListView (for sidebar calendars) and DetailView (for events on each calendar).

Here are my views:

class DetailView(generic.DetailView):
    model = Calendar
    template_name = 'koledarji/detail.html'

class CalendarsView(generic.ListView):
    template_name = 'koledarji/calendars.html'
    context_object_name = 'calendars_list'
    def get_queryset(self):
        return Calendar.objects.all()

With that approach my details on every specific calendar are ok, but I lose my list of calendars on the sidebar nav menu.

My url for specific calendar:

url(r'^(?P<pk>[0-9]+)$', views.DetailView.as_view(), name='detail'),

and a part of my template:

{% extends 'prijavljen/calendar.html' %}

{% block cal_name %}

    {% for calendar in calendars_list %}
        {% if request.path == '/prijavljen/'|add:calendar.id %}
            {{calendar.name }}
        {% endif %}
    {% endfor %}
{% endblock %}

After that code I want to make a list of events, but for example even name of calendar should be enough to solve.

I've tried to solve that with comparing request.path with path od calendar that I want, but also doesn't work.

Any help would be appreciated.

Upvotes: 6

Views: 7912

Answers (2)

Kritz
Kritz

Reputation: 7311

It would be better to use a ListView as you probably still want to use pagination. Something like this:

class DetailListView(ListView):
    detail_context_object_name = 'object'

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        return super(DetailListView, self).get(request, *args, **kwargs)

    def get_queryset_for_object(self):
        raise NotImplementedError('You need to provide the queryset for the object')

    def get_object(self):
        queryset = self.get_queryset_for_object()
        pk = self.kwargs.get('pk')
        if pk is None:
            raise AttributeError('pk expected in url')
        return get_object_or_404(queryset, pk=pk)

    def get_context_data(self, **kwargs):
        context = super(DetailListView, self).get_context_data(**kwargs)
        context[self.detail_context_object_name] = self.object
        return context

Upvotes: 10

George Griffin
George Griffin

Reputation: 754

You could modify the DetailView class and add a get_context_data() method. This will allow you to inject extra context, in this case, your Calendars.objects.all() queryset, into your detail view.

class MyDetailView(generic.DetailView):
    model = Calendar
    template_name = 'koledarji/detail.html'
    def get_context_data(self, *args, **kwargs):
        context = super(MyDetailView, self).get_context_data(*args, **kwargs)
        context['calendars_list'] = Calendar.objects.all()
        return context

Upvotes: 11

Related Questions