Python Forum
Displaying list of lists in template
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Displaying list of lists in template
#1
Hi,

I'm trying to create a list of url links in categories on a site at work, they use about 80 web based tools for content discovery and other things. I have built the site using django and currently the links are all hard coded into the side bar. This would usually be fine, but the links change on a daily basis as there are so many and tools migrate to different servers etc, so I wanted to serve the links dynamically, but I struggling to find out how this is done. In the python I have learned, I would just do:
for i in categories:
    print(i)
    for j in links:
        print(j)
But I can't seem to do that in django. So far I am only able to use one model per view and one view per template, so I haven't a clue as to how you would do this. Ultimately I will be using the nested loops in the template so that I can get the javascript that opens and closes the nested links correctly, but can't figure out how to take a category from the category model and the links from the links model. I tried using the foreign key only to have the category name printed as many times as there is links in the category. There are basically 10 categories and anything from 3 links to 20+ links in each category.

Any pointers would be really helpful as I have been through the django tutorial and I have nearly finished a full on course on Django that has taken me a good 3 months to go through and unfortunately, that does not cover this issue either. I'm assuming there is a way to work with multiple models, as I thought that was the the point to have two or more tables and take data from both, but django does not make this easy for newbies.

This is what I have so far:
model.py
from datetime import datetime
from django.db import models


class Category(models.Model):
    '''
    Category of links in the Sidebar
    '''
    name = models.CharField(max_length=30,unique=True)

    def __str__(self):
        return self.name


class Link(models.Model):
    
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    date = models.DateTimeField(auto_now_add=True)
    name = models.CharField(max_length=24,unique=True)
    url = models.URLField(unique=True)

    def __str__(self):
        return self.name
view.py
from django.shortcuts import render, redirect
from django.template import RequestContext
from django.views.generic import View,TemplateView,ListView,DetailView
from . import models


class TestpageView(ListView):
    context_object_name = 'link_tree'
    model = models.Link
I can work with the other areas of django, settings urls etc. but trying to work with the logic in django is really tricky. Any pointers would be really appreciated.
Reply
#2
1) create ./templates/main.html with the following content:
Output:
<ul> {% for category in categories %} <li> {{category.name}} {%if category.link_set%} <ul> {%for link in category.link_set.all%} <li>{{link.name}}</li> {%endfor%} </ul> {%else%} :without children links {%endif%} </li> {%endfor%} </ul>
views.py:
....
# Use category model instead of link
class TestPageView(ListView):
    context_object_name = 'categories'
    model = models.Category
    template_name='main.html'
urls.py (or something like this):

from django.contrib import admin
from django.urls import path

from main.views import TestPageView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('testing/', TestPageView.as_view(), name='listing-links')
]
This works as expected in Django 2.1.4;


In general, if you need to render categories (nested categories) and related links,
it would be better to implement a custom tag. This custom tag could be recursively invoked in the template
to handle hierarchy of categories.
Reply
#3
Hi thank you, that's perfect. I can see now what I was missing, which was the 'link_set', and having done a bit of research, I can see that the '_set' is a reverse lookup class variable, that in my interpretation, is the reference to the other model.

Django decided what my template was called as it was calling for a template called category_list.html, so renaming the template to that solved that one and I can see the connection, there. Where I am a little lost is, the line:
template_name='main.html
I was expecting that to over ride Django's default, but it still wanted category_list.html not main.html, I think I may have missed a setting somewhere that hasn't been highlighted in this thread.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020