Django template doesn't render models as I would expect - python

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.

Related

How can I use slice filter in Django?

How can I filter content like 0-9 then 9-18 then 18-28 and so on.. in Django using a slice filter or any other option?, SO please suggest me.
<li class="mega-title"><span>column 01</span>
<ul>
{% for category in categories %}
{% for subcategory in category.children.all|slice:":9" %}
<li>{{subcategory.title}}</li>
{% endfor %}
{% endfor %}
</ul>
</li>
<li class="mega-title"><span>column 02</span>
<ul>
{% for category in categories %}
{% for subcategory in category.children.all|slice:"[09:9]" %}
<li>{{subcategory.title}}</li>
{% endfor %}
{% endfor %}
</ul>
</li>
Django slice filter: https://docs.djangoproject.com/en/dev/ref/templates/builtins/#slice
{% for subcategory in category.children.all|slice:":9" %}
{% for subcategory in category.children.all|slice:"10:18" %}
....

How to display date from database in Django form without day

I was looking for a solution but nowhere to find the right answer. Maybe the answer I am looking for does not exist, so I decided to ask a question here just in case.
I try to show a date without a day. But the problem is that the date is displayed as one of form fields that I create from the model in the database. I explained this because I am not trying to show only the date separately in the temple but the whole form. I'm showing the form in the template using {{form.as_p}}. My date always shows dd.mm.YYYY, but I want to display a date without a day. The form is used to update existing data in the database. Is there a solution, to define certain parameters in the form class I created in the forms.py file or I must do something else?
Suppose this is your forms.py
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length=30)
email = forms.EmailField(max_length=254)
message = forms.CharField(
max_length=2000,
widget=forms.Textarea(),
help_text='Write here your message!'
)
source = forms.CharField( # A hidden input for internal use
max_length=50, # tell from which page the user sent the message
widget=forms.HiddenInput()
)
You can render it manually like this:
<form method="post" novalidate>
{% csrf_token %}
{% if form.non_field_errors %}
<ul>
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
{% for hidden_field in form.hidden_fields %}
{% if hidden_field.errors %}
<ul>
{% for error in hidden_field.errors %}
<li>(Hidden field {{ hidden_field.name }}) {{ error }}</li>
{% endfor %}
</ul>
{% endif %}
{{ hidden_field }}
{% endfor %}
<table border="1">
{% for field in form.visible_fields %}
<tr>
<th>{{ field.label_tag }}</th>
<td>
{% if field.errors %}
<ul>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
{{ field }}
{% if field.help_text %}
<br />{{ field.help_text }}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<button type="submit">Submit</button>
</form>
Now you can apply date filter to your fields:
{{ value|date:"D d M Y" }}
You can read more about date filter as pre your need i.e., to get only date or time : https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#date

How to count authors in Pelican Blogs?

I was trying to make my blog show "Authors" instead of "Author" when there are more than 1 authors for the same article.
The solution (thanks to #Avaris) is to set i = article.authors|count and that can be used as follows
<div align="right">
{% set i = article.authors|count %}
{% if i != 1 %}
Authors:<br>
{% endif %}
{% if i == 1 %}
Author:<br>
{% endif %}
{% if article.authors %}
{% for author in article.authors %}
{{ author }}<br>
{% endfor %}
{% endif %}
</div>
This is different to Set variable in jinja because in Pelican I cannot find a command like lenght(authors) to obtain a number to define a condition.

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 #}

django-mptt not linking data together correctly

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.

Categories

Resources