django entries of author - python

I need to get list of all authors and their publishes
{% for author in authors %}
{{ author.name }}
{% for publish in publishes %}
{{ publish.title }}
{% endfor %}
{% endfor %}
views.py:
def authors_list(request):
authors = Author.objects.all()
publishes = Group.objects.filter(author=author)
return render(request, 'app/authors_list.html', {'authors': authors,'publishes': publishes})
This way 'publishes' is not Defined.

Assuming you have a ForeignKey in Group model, You could do something like this,
{% for author in authors %}
{{ author.name }}
{% for publish in author.group_set.all() %}
{{ publish.title }}
{% endfor %}
{% endfor %}
You could access the groups of your authors with the related name.
For that, you can also define a related_name for your convenience.
You could add,
author = models.ForeignKey(Author, related_name='groups')
in your Group model.
If you have added the related_name, then you can call the related_objects like,
{% for publish in author.groups.all() %}
in your template.
Then change your views,
def authors_list(request):
authors = Author.objects.all()
return render(request, 'app/authors_list.html', {'authors': authors})

The problem is that publishes is not defined while you are trying to define publishes
It is misleading but the error is marked below:
publishes = Group.objects.filter(publishes=publishes)
^^^^^^^^^
I hope it will help you find the problem.
After your edit:
publishes = Group.objects.filter(author=author)
^^^^^^
I think you will need to define a #propery for Author:
Read this

Related

Render relationship model in template

I am trying to render a model with a relationship but I am not able to do so.
class LogBook(models.Model):
name = models.CharField(max_length=50, verbose_name="Nom du registre de maintenance")
members = models.ManyToManyField(User)
class LogMessages(models.Model):
logbook = models.ForeignKey(LogBook)
message = models.CharField(max_length=200, verbose_name="Détail du problème")
class LogDone(models.Model):
logmessage = models.ForeignKey(LogMessages)
message = models.CharField(max_length=200)
My view:
log = get_object_or_404(LogBook, pk=log_id)
logmessages = LogMessages.objects.filter(logbook=log_id)
My template
{% for logmessage in logmessages.all %}
{{logmessage.logdone.message}}
{{% endfor %}}
But the logdone object is not showing, any idea ?
Since your LogMessage model has a foreign key to log done, it's not a One to One relation and you have to access the related LogDone objects using the _set notation. There's also a slight typo, I believe. It should logmessages and not logmessages.all
{% for logmessage in logmessages %}
{% for done in logmessage.logdone_set.all %}
{{ done.message }}
{% endfor %}
{% endfor %}
I forgot that I added a related_name equal to "logdones" so I did the following :
{% for logmessage in logmessages %}
{% for done in logmessage.logdones.all %}
{{ done.message }}
{% endfor %}
{% endfor %}
And now it is working, thanks to #Vishal

newbie - understanding Django's class-based views dynamic filtering

I'm trying to follow and learning about dynamic filtering in Django from the docs. https://docs.djangoproject.com/en/1.10/topics/class-based-views/generic-display/#dynamic-filtering
I've just been following along step by step and copy/pasted the code from docs. But I don't understand the last bit about added the publisher into the context, meaning I can't figure out how to query that data in the template. The only thing I can get a "hold" of publisher.
Because in the PublisherDetail view publisher_detail.html you would just do something straight forward like this, to list all the books from a publisher:
{% for book in book_list %}
{{ book.title }}
{% endfor %}
This is part that is tripping me up.
We can also add the publisher into the context at the same time, so we
can use it in the template:
# ...
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(PublisherBookList, self).get_context_data(**kwargs)
# Add in the publisher
context['publisher'] = self.publisher
return context
Setting context['publisher'] = self.publisher in get_context_data means you can display the publisher's details in the context. For example, you could display the publisher's name above the list of book titles with:
<h2>Books published by {{ publisher.name }}</h2>
{% for book in book_list %}
{{ book.title }}
{% endfor %}
You can access related objects as described here: What is `related_name` used for in Django? .
Try calling either publisher.books.all() or publisher.book_set.all():
{% for book in publiser.book_set.all %}
{{ book.title }}
{% endfor %}

Django: How to display author of query of posts?

I'm trying to make individual pages for each author showing their name and posts. I can't seem to get the username displayed.
views.py
class UserProfileView(generic.ListView):
template_name = 'howl/user-profile.html'
context_object_name = 'user_howls'
def get_queryset(self):
author = self.request.user
u = User.objects.get(username=author)
return Howl.objects.filter(author=u)
models.py
class Howl(models.Model):
author = models.ForeignKey(User, null=True)
content = models.CharField(max_length=150)
Here is where I'm stuck.
user-profile.html
{% extends 'howl/base.html' %}
{% block content %}
<h1>User: {{user_howl.author}}</h1>
{% for user_howl in user_howls %}
<ul>
<li>{{user_howl.content}}</li>
</ul>
{% endfor %}
{% endblock %}
The content is displayed just fine, but the heading just says "User: ", how do I give it a context without using a for loop?
I've tried:
{% for author in user_howls.author %}
<h1>User: {{author}}</h1>
{% endfor %}
and
{% if user_howls.author %}
<h1>User: {{user_howl.author}}</h1>
{% endif %}
Still the same outcome, displaying "User: "
user_howls is a queryset so it won't have an author attribute, you need to get the author of the iterated object
{% for howl in user_howls %}
<h1>User: {{ howl.author}}</h1>
{% endfor %}
More to the point though, it doesn't make sense to start from a Howl list, when you are just returning the results for the user_profile, nor does it make sense to use a ListView. so instead, start from the user and then look up its howls
user_obj.howl_set.all()
Since your queryset is based on the posts belonging to the current user, you can shortcut all of this and just show the user directly:
User: {{ user }}

Custom template tags

I have a model name "Attendee". In that there are foreignkeys as user and model named "Event".
Now I have to get the users of Attendee who are going for event.
{% get_event_attendee event as attending_event %}
it works for me. But I need this step with "for",
I mean
{% get_event_attendee for event as attending_event %}
Please help.
Thanks
Here you go.
https://djangosnippets.org/snippets/1919/
Previous I had a damn thing to do. Go through with that you will definitely crack that :)
If your models look like this
from django.db import models
class User(models.Model):
...
class Event(models.Model):
...
class Attendee(models.Model):
user = models.ForeignKey(User)
event = models.ForeignKey(Event)
you can access the attendees in the template like this:
{% for attendee in event.attendee_set.all %}
{{ attendee.user }}
{% endfor %}
Is this your question?
If you have multiple events you can use two forloops:
{% for event in event_list %}
{% for attendee in event.attendee_set.all %}
{{ attendee.user }}
{% endfor %}
{% endfor %}

Iterating over related objects in Django: loop over query set or use one-liner select_related (or prefetch_related)

I have a newsletter application where a newsletter has multiple articles within each issue. I want to display a summary page online that lists the newsletter year, volume and label, and then in an unordered list display all the articles in the issue. I am quite new to Django so I am trying to determine the best way to do this.
I have the models defined (just the relevant parts):
Models.py:
class Newsletter(models.Model):
volume = models.ForeignKey(Volume)
year = models.IntegerField()
season = models.CharField(max_length=6, choices=VOLUME_SEASON)
label = models.CharField(max_length=20)
number = models.IntegerField()
class Article(models.Model):
newsletter = models.ForeignKey(Newsletter)
section = models.ForeignKey(Section)
title = models.CharField(max_length=200)
What I want to see on the web looks like:
<h2>Spring 2012</h2>
<p>Volume 14, Number 1</p>
<ul>
<li>Foo</li>
<li>Bar</li>
<li>Baz</li>
</ul>
<h2>Winter 2011</h2>
<p>Volume 13, Number 4</p>
<ul>
<li>Boffo</li>
</ul>
Pretty simple. However, I am confused by the best way to write my view. Whether to use:
Two lists which I zip() and then iterate over in the template
Use the select_related() queryset
Use the prefetch_related() queryset
I have it working using the first option:
Views.py:
from django.shortcuts import render_to_response, get_object_or_404
from www.apps.newsletter.models import Newsletter, Article
def index(request):
article_group = []
newsletter = Newsletter.objects.all().order_by('-year', '-number')
for n in newsletter:
article_group.append(n.article_set.all())
articles_per_newsletter = zip(newsletter, article_group)
return render_to_response('newsletter/newsletter_list.html',
{'newsletter_list': articles_per_newsletter})
And then render it using the following template:
Newsletter_list.html:
{% block content %}
{% for newsletter, articles in newsletter_list %}
<h2>{{ newsletter.label }}</h2>
<p>Volume {{ newsletter.volume }}, Number {{ newsletter.number }}</p>
<p>{{ newsletter.article }}</p>
<ul>
{% for a in articles %}
<li>{{ a.title }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}
Pretty straightforward, but as I am pretty new to Django I was wondering if what I am doing is completely inefficient in terms of its powerful ORM. I would love to not have to make a list on-the-fly and then zip() the two lists together if there is a faster way.
TIA.
The approach you are doing now will be heavily inefficient, because it will result in an 1+N number of queries. That is, 1 for the query of all your Newsletters, and then 1 for every single time you evaluate those n.article_set.all() results. So if you have 100 Newletter objects in that first query, you will be doing 101 queries.
This is an excellent reason to use prefetch_related. It will only result in 2 queries. One to get the Newsletters, and 1 to batch get the related Articles. Though you are still perfectly able to keep doing the zip to organize them, they will already be cached, so really you can just pass the query directly to the template and loop on that. :
view
newsletters = Newsletter.objects.prefetch_related('article_set').all()\
.order_by('-year', '-number')
return render_to_response('newsletter/newsletter_list.html',
{'newsletter_list': newsletters})
template
{% block content %}
{% for newsletter in newsletter_list %}
<h2>{{ newsletter.label }}</h2>
<p>Volume {{ newsletter.volume }}, Number {{ newsletter.number }}</p>
<p>{{ newsletter.article }}</p>
<ul>
{% for a in newsletter.article_set.all %}
<li>{{ a.title }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}

Categories

Resources