How to loop within a loop in django while passing multiple context - python

I having trouble trying to access the foreign key element from my template. I am trying to pass multiple contexts using class view like this:
class HomeView(ListView):
template_name = "homepage/home.html"
queryset = Author.objects.all()
def get_context_data(self, **kwargs):
context = super(HomeView, self).get_context_data(**kwargs)
context['author_links'] = Author_link.objects.all()
context['categories'] = Category.objects.all()
context['extra_links'] = Extra_link.objects.all()
context['poems'] = Poem.objects.all()
return context
my models.py file:
class Author(models.Model):
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class Author_link(models.Model):
url_text = models.CharField(max_length=100)
url = models.CharField(max_length=200)
author = models.ForeignKey(Author)
def __str__(self):
return self.url_text
class Category(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
class Meta:
verbose_name_plural = 'categories'
def __str__(self):
return self.name
class Extra_link(models.Model):
url_text = models.CharField(max_length=100)
url = models.CharField(max_length=200)
category = models.ForeignKey(Category)
def __str__(self):
return self.url_text
however when I am trying to loop through the context I can't seem to access the foreign key of each item:
{% for author in object_list %}
<li class = "collection-item">
<ul class="collapsible" data-collapsible="accordion">
<li>
<div class="collapsible-header">{{author.name}}</div>
<div class="collapsible-body">
{% for item in author.item_set.all %}
<p>{{item.url}}</p>
{% endfor %}
</div>
</li>
</ul>
</li>
{% endfor %}
what I am trying to do is loop through the authors and at the same time under each author loop through the urls that are associated with each author.

where you have
{% for item in author.item_set.all %}
<p>{{item.url}}</p>
{% endfor %}
you should have something like
{% for item in author.author_link_set.all %}
<p>{{item.url}}</p>
{% endfor %}
This manager (author.author_link_set) is added to each author because there is a foreign key from Author_link to Author.
side note: the convention for class names in python is Pascal Case, e.g., AuthorLink not Author_link. I mention this because I'm not 100% sure if I have correctly guessed the name of the reverse relation on author (it might be author.authorlink_set, I've never seen an underscore in a model name - django may do something special in that case)

Related

Same Dynamic Data coming in every column of webpage

I am doing CRUD using serializers, foreignkeys and I am trying to dynamically list the categories, sub_categories. For example category = 9-6 wear and its subcategories are kurta, skirtset, dress, kurtaset. I want these subcategories below only 9-6wear
The issue is that other subcategories are also mentioning kurta,skirtset,dress and kurtaset which I dont want as shown below
I have tried for hours but without much success
below are my models
class Products(models.Model):
categories = models.ForeignKey(Categories,on_delete=models.CASCADE)
sub_categories = models.ForeignKey(SUBCategories,on_delete=models.CASCADE)
color = models.ForeignKey(Colors,on_delete=models.CASCADE)
size = models.ForeignKey(Size,on_delete=models.CASCADE)
image = models.ImageField(upload_to = 'media/',width_field=None,height_field=None,null=True)
title = models.CharField(max_length=70)
price = models.CharField(max_length=10)
sku_number = models.CharField(max_length=10)
product_details = models.CharField(max_length=1000)
quantity = models.IntegerField(default=0)
isactive = models.BooleanField(default=True)
class Category(models.Model):
#made changes to category_name for null and blank
category_name = models.CharField(max_length=30)
category_description = models.CharField(max_length=30)
isactive = models.BooleanField(default=True)
class SUBCategories(models.Model):
category_name = models.ForeignKey(Categories, on_delete=models.CASCADE)
sub_categories_name = models.CharField(max_length=30)
sub_categories_description = models.CharField(max_length=30)
isactive = models.BooleanField(default=True)
below are the serializer
class CategoriesSerializer(serializers.ModelSerializer):
class Meta:
model = Categories
fields = "__all__"
extra_kwargs = {'category_name': {'required': False}}
class POLLSerializer(serializers.ModelSerializer):
class Meta:
model = Products
fields = "__all__"
below is my shoppingpage function
def shoppingpage(request):
cat = Categories.objects.filter(isactive=True)
category = CategoriesSerializer(cat,many=True)
subcat = SUBCategories.objects.filter(isactive=True)
subcategory = SUBCategoriesSerializer(subcat,many=True)
return render(request,'polls/shoppingpage.html',{'category':category.data,'subcategory':subcategory.data})
below is my shoppingpage.html for loop part
{% for result in category %}
<div class="col-md-3">
<div class="lynessa-listitem style-01">
<div class="listitem-inner">
<a href="/9-6wear" target="_self">
<h4 class="title">{{result.category_name}}</h4>
</a>
{% for ans in result.subcategory_set.all %}
<ul class="listitem-list">
<li>
{{ans.sub_categories_name}}
</li>
</ul>
{% endfor %}
</div>
</div>
</div>
{% endfor %}
help is greatly appreciated, thanks!
It's because you are just looping through all the subcategories for all of the categories in your template:
{% for result in category %}
...
{% for ans in subcategory %}
You should change the second loop so that it only refers to related subcategories:
{% for ans in result.subcategory_set.all %}
Edit
Serializers aren't necessary in this example, nor is the subcategory queryset. The view can look like this:
def shoppingpage(request):
categories = Categories.objects.filter(isactive=True)
context = {'categories': categories}
return render(request,'polls/shoppingpage.html', context)
Edit
A lot of the errors came down to context/variable misalignment:
# models.py
model Category
...
model Subcategory
...
# views.py
context = {'categories': Category.objects.all()}
# template
{% for category in categories %}
{% for subcategory in category.subcategory_set.all %}
...

How to pass parameter in current url to an html template in Django 3

I have:
Movie Model
class Movie(models.Model):
title = models.CharField(max_length=255)
synopsis = models.TextField()
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE,
)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('movie_detail', args=[str(self.id)])
Discussion Model
class Discussion(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE,
)
date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
movie = models.ForeignKey(
Movie,
on_delete=models.CASCADE,
related_name='discussion',
)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('discussion_detail', args=[str(self.movie.id), str(self.id)])
DiscussionListView
class DiscussionListView(LoginRequiredMixin, ListView):
model = Discussion
template_name = 'discussion_list.html'
login_url = 'login'
And I also have discussion_list.html
Here is what I want:
I’m in the url /article/1/discussion/. The integer 1 is a movie_pk because the url is defined as /article/<int:movie_pk>/discussion/ which in this case refer to the priority key of a Movie Model, for example StarWars I. This is a page of list of discussion titles related to this movie. (This has already been achieved)
There is a button “New” where, if i click on it, I will be directed to /article/1/discussion/new. There, I can create a new discussion. (The feature I want to add)
However:
In discussion_list.html, we require the url tag {% url discussion_new %} to have a parameter since discussion_new is defined as /article/<int:movie_pk>/discussion/new
Thus:
How to pass the movie_pk from the current url, then to DiscussionListView, then to the template discussion_list.html?
In detail view's template, you can send the object.id as parameter of url:
#template
{% url "discussion_new" movie_pk=object.pk %}
If you are in a List View template then probably you have a loop to go through all object_list. There you can implement like this:
{% for object in object_list %}
{% url "discussion_new" movie_pk=object.pk %}
{% endfor %}
{% url discussion_new %}
to
{% url "discussion_new" pk=movie_pk%}
And in list
{% for m in movie_list %}
{% url "discussion_new" movie_pk=m.pk %}
{% endfor %}

Can I use filter() in django template?

What I'd like to do is using filter() in django template like belows:
models.py
from django.db import models
From Django. utils import Timezone
class Category(models.Model):
url = models.CharField(max_length=200)
site_name = models.CharField(max_length=50)
board_name = models.CharField(max_length=50)
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField(blank=True)
category = models.ForeignKey(Category)
created_date = models.DateField(blank=True, null=True)
crawl_date = models.DateTimeField()
num_of_comments = models.PositiveSmallIntegerField(default=0, blank=True, null=True)
notice = models.BooleanField(default=False)
views.py
def post_list(request, site_name=None, page=1):
categories = Category.objects.filter(site_name=site_name.upper()).order_by('board_name')
return render(request, 'SNU/post_list.html', {'site_name':site_name.upper(), 'categories':categories})
post_list.html
{% for category in categories %}
<p> {{category}} </p>
{% for post in category.post_set.filter(notice=True) %}
<li>{{ post.title }}</li>
{% endfor %}
{% endfor %}
In post_list.html, {% for post in category.post_set.filter(notice=True) %} occurs error. Only category.post_set.all is the one that I can use in template?
You can do it on view level by
def post_list(request, site_name=None, page=1):
categories = Category.objects.filter(site_name=site_name.upper(),
notice=True).order_by('board_name')
return render(request, 'SNU/post_list.html',{'site_name':site_name.upper(),
'categories':categories})
If for some reason you need all categories, not just those having notice = True,
add one more query without notice=True in filter and pass it in the dictionary.
Alternatively, you can create custom tag and provide filter - see https://docs.djangoproject.com/en/1.9/howto/custom-template-tags/

Save in DB from Listview Django with a form in template

im building a little survey app, I need to show each answer with their corresponding answers in one page, so im doing it with ListView and paginate by 1.
class TriviaView(ListView):
model = Preguntas
paginate_by = 1
template_name = 'trivias.html'
Obviously each answer has to be save it in database, but here is where i get lose, i dont know how to save in DB each answer the user reply.
Template:
<form action="." method="post">{% csrf_token %}
<p>{% for pregunta in object_list %} {{pregunta.pregunta}}</p>
{% for respuesta in pregunta.respuestas_set.all %}
{% if page_obj.has_next %}
<button type="button">{{respuesta.respuesta}}</button>
{% endif %}
{% endfor %}
{% endfor %}
</form>
Models:
class Trivia(models.Model):
nombre = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
categoria = models.ForeignKey(Categorias)
contador = models.IntegerField()
def __str__(self):
return self.nombre
class Meta():
verbose_name_plural = "Trivias"
class Preguntas(models.Model):
trivia = models.ForeignKey(Trivia)
pregunta = models.CharField(max_length=100)
def __str__(self):
return self.pregunta
class Meta():
verbose_name_plural = "Preguntas"
class Respuestas(models.Model):
pregunta = models.ForeignKey(Preguntas)
respuesta = models.CharField(max_length=100)
def __str__(self):
return self.respuesta
class Meta():
verbose_name_plural = "Respuestas"
class Records(models.Model):
trivia = models.ForeignKey(Trivia)
user = models.CharField(max_length=200)
pregunta = models.CharField(max_length=200)
respuesta = models.CharField(max_length=200)
def __str__(self):
return self.user
How can i save in Records model each answer the user pick with their corresponding answer?.
Sorry for the spanish attributes, the client ask it like that.
Thanks in advance.
You would want to use the Related Objects syntax.
Usage would be:
# get one question
p = Preguntas.objects.get(pk=1)
# get all responses
p.respuestas_set.all()
The Django Docs are here:
https://docs.djangoproject.com/en/1.7/topics/db/queries/#related-objects

django inability to find blog url while rendering the html page

I am newbie to django. I am trying to develop blog app in django.
I trying to render my fetched data into html but unable to do it for the following code
for which it is printing no blog found even data is being fetched properly.
This is my views.py
def blogpost(request):
latest_blog_list = BlogPost.objects.order_by('-pub_date')[:5]
print "" + str(latest_blog_list)
context = {'latest_poll_list' : latest_blog_list}
print "" + str(context)
#I can see the data is being fetched properly
return render(request,'polls/blogPostlist.html',context)
my blogPostlist.html
{% if latest_blog_list %}
<ul>
{% for blogpost in latest_blog_list %}
<li> <a href="/blog/{{ blogpost.slug }}"> blogpost.title </li>
{% endfor %}
</ul>
{% else %}
<p> test No blog avilable</p>
{% endif %}
models.py
class BlogPost(models.Model):
title = models.CharField(max_length=255)
description = models.CharField(max_length=255)
post = models.TextField()
#media_file = models.ImageField(upload="")
pub_date = models.DateTimeField()
visit_count = models.IntegerField(default=0)
slug = models.SlugField(unique=True, max_length=255)
published = models.BooleanField(default=True)
tag = models.ManyToManyField(BlogTag)
catagory = models.ManyToManyField(BlogCategory)
def __unicode__(self):
return u'%s' % self.slug
class Meta:
ordering = ["pub_date"]
Along with that if I want to get title and slug for the blog, how to do it?
The context key name is wrong:
context = {'latest_poll_list' : latest_blog_list}
Instead it should be:
context = {'latest_blog_list' : latest_blog_list}

Categories