django-mptt not linking data together correctly - python

Hay, I'm using MPTT to create some tree-like data from a model which contains conversations, and i want them to be ordered by a 'votes' field.
The model looks like this at the moment, very basic.
class Thread(MPTTModel):
message = models.CharField(max_length=100)
parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
votes = models.IntegerField()
class MPTTMeta:
order_insertion_by=['votes']
As you can see, we have a message field, and parent FK which is linked to the Thread model, and a votes.
Within my views i have this
threads = Thread.tree.all()
data = {
'threads':threads
}
return render_to_response("show.html",data )
then within my template
{% load mptt_tags %}
<ul class="root">
{% recursetree d %}
<li>
{{ node.title }}
{% if not node.is_leaf_node %}
<ul class="children">
{{ children }}
</ul>
{% endif %}
</li>
{% endrecursetree %}
</ul>
However, the outputted list is a a list of all the threads. None of them are linked together.
Any ideas?

{% load mptt_tags %}
<ul class="root">
{% recursetree nodes %}
<li>
{{ node.message }}
{% if not node.is_leaf_node %}
<ul class="children">
{{ children }}
</ul>
{% endif %}
</li>
{% endrecursetree %}
</ul>
In views I have:
threads = Thread.tree.all()
data = {
'nodes':threads
}
return render_to_response("show.html",data )
In the html page I see a tree of nodes order alphabetically and with indentation.

Related

Django mptt recursetree with get_cached_trees in template

In View:
context['categories'] = = models.Category.objects.all().get_cached_trees()
In template:
{% load mptt_tags %}
<ul>
{% recursetree categories %}
<li>
{{ node.name }}
{% if not node.is_leaf_node %}
<ul class="children">
{{ children }}
</ul>
{% endif %}
</li>
{% endrecursetree %}
</ul>
As a result, it renders only first level of queryset. If remove get_cached_trees it renders all tree. How to render all tree with get_cached_trees?
You don't actually need to call get_cached_trees() in this situation because recursetree already does the caching for you.
From the documentation:
Iterates over the nodes in the tree, and renders the contained block for each node.
This tag will recursively render children into the template variable {{ children }}.
Only one database query is required (children are cached for the whole tree)

How to show a certain number of levels in django-mptt?

In my Django project I use django-mptt application to create hierarchical tree. Right now next code works well but I want to show only first 4 level of the tree. How to make it correctly? I am confused.
views.py:
context['caregories'] = Category.objects.get(id=5).get_descendants()
html:
{% load mptt_tags %}
<ul>
{% recursetree caregories %}
<li>
{{ node.name }}
{% if not node.is_leaf_node %}
<ul class="children">
{{ children }}
</ul>
{% endif %}
</li>
{% endrecursetree %}
</ul>
You can filter the descendants by their level
obj = Category.objects.get(id=5)
context['caregories'] = obj.get_descendants().filter(level__lte=obj.level + max_depth)
where max_depth is the depth you require

Django template doesn't render models as I would expect

So I have this Lecture class. Now for this class, I have 2 choices: "Classes" and "Seminars", and I want that each time I add a lecture to either one, the template will shows firstly the choice and then all the lectures.
Example: Classes will have Lecture1, Lecture2, Lecture3 etc.
Problem is that right now when I iterate, choice shows each time, for every lecture and I want each choice to show only ONCE.
class Lecture(models.Model):
course = models.ForeignKey('Course', on_delete=models.CASCADE, default='', related_name='lectures')
lecture_category = models.IntegerField(choices=((0, "Classes "),
(1, "Seminars"),
))
lecture_title = models.CharField(max_length=100)
content = models.TextField()
link = models.URLField(blank=True)
file = models.FileField(upload_to='documents', blank=True)
def __str__(self):
return self.lecture_title
<ul>
{% for c in lectures %}
<b>{{ c.get_lecture_category_display }}</b>
<p>.......................</p>
<li>{{ c.lecture_title }}</li>
<li>{{ c.content }}</li>
{% if c.link %}
<li>{{ c.link }}</li>
{% if c.file %}
<li><a href='{{ MEDIA_URL }}{{ c.file.url }}'>download</a></li>
{% endif %}
{% endif %}
{% endfor %}
<hr/>
</ul>
There is a template tag called regroup that you can use for this. See the regroup section at https://docs.djangoproject.com/en/2.0/ref/templates/builtins/
{% regroup lectures by lecture_category as category_list %}
<ul>
{% for category in category_list %}
<li>{{ category.grouper }}
<ul>
{% for c in category.list %}
<li>{{ c.lecture_title }}</li>
<li>{{ c.content }}</li>
...etc
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
Edit:
As Daniel Rosemen pointed out, you will also have to sort the query by the field you want to regroup on in your view. In this case you would have to order lectures by lecture_category. The above method will not work otherwise.

Multiple Models in the single View (django, python)

.Hello everyone! I am a beginner in Django and I know that this question was asked hundrets of times on SO, but I still can't get it. I tried to use two models in the same IndexView, but it just repeats the elements which contains in the Petition model.
class IndexView(generic.ListView):
template_name = 'home.html'
context_object_name = 'home_list'
model = Petition
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context['petition'] = Petition.objects.all()
context['law'] = Law.objects.all()
return context
And here is a relevant part of the template:
{% if home_list %}
<ul>
{% for petition in home_list%}
<li>{{ petition.question }}</li>
<img src="{{ petition.image.url }}" height="200" width="300">
{% endfor %}
</ul>
{% else %}
<p>No petitions are available.</p>
{% endif %}
{% if home_list %}
<ul>
{% for law in home_list %}
<li>{{ law.question }}</li>
<img src="{{ law.image.url }}" height="200" width="300">
{% endfor %}
</ul>
{% else %}
<p>No laws are available.</p>
{% endif %}
You're defining your law list in the context as law but then you never reference it, you should be looping over these instead of home_list
{% if law %}
{% for l in law %} {# law is already defined so cant be used as scope var #}

How To Access Many to Many Attribute in Django

I am very new to web development and I have created a sample project using Django. So far I have a Django powered page that displays the contents of one of my database's model objects which is called Publications. The code I have in my view template is:
<html><head><title>Publications</title></head>
<body>
<h1>Publications</h1>
<ul>
{% for publication in publication_list %}
<li>{{ publication.title }} </li>
{% endfor %}
</ul>
</body></html>
This works fine, but now I would like to access and display a many to many attribute on Publications called Tags. I have tried adding another for tag as follows:
<html><head><title>Publications</title></head>
<body>
<h1>Publications</h1>
<ul>
{% for publication in publication_list %}
<li>{{ publication.title }} </li>
{% for tag in publication_list.tags %}
<li>{{ tag.title }} </li>
{% endfor %}
{% endfor %}
</ul>
</body></html>
I realize this is quite wrong, but I don't see how to access the Tags model. For reference, my function for displaying the publications in the view is:
def display_publications(request):
publication_list = Publication.objects.order_by('title')[:10]
return render(request, 'publications.html', {'publication_list': publication_list})
And my Publications and Tag Models are:
class Tag(models.Model):
title = models.CharField(max_length=50)
class Publication(models.Model):
title = models.CharField(max_length=200)
tags = models.ManyToManyField(Tag, blank=True)
Any help is appreciated.
What you are doing only accesses the ManyRelatedManager. You need to specify a query against that manager. In python, it would be:
publication.tags.all()
In a django template it would be:
{% for tag in publication.tags.all %}
{{ tag }}
{% endfor %}
This should be covered in the official documention on many-to-many relationships.
Edit: Here's a good example of how many-to-many relationships work: https://docs.djangoproject.com/en/1.5/topics/db/examples/many_to_many/
Because you seem to be having some trouble with this, given your comments on the other question, here are the changes to the template. You do not need to modify the view at all from what you have given above.
{% for publication in publication_list %}
<li>{{ publication.title }}
<ul>
{% for tag in publication.tags.all %}
<li>{{ tag.title }} </li>
{% endfor %}
</li>
</ul>
{% endfor %}

Categories

Resources