What is the best approach to create a model field in Django, so that in template, I can iterate over its objects as:
<ul>
{% for item in ModelName.fieldname %}
<li>{{ item }}</li>
{% endfor %}
</ul>
so It output something like, lets say:
<h1>Apple Products</h1>
<ul>
<li>Ipod</li>
<li>Apple</li>
<li>Ipod mini</li>
<li>Display XDR</li>
<li>Macbook Pro</li>
</ul>
My thoughts:
Create a separate model and then reference it as foreign key to parent model.
create a CharField and separate each list item with comma, then create a function; return a list and loop over list of separated items by comma.
Kindly share your idea, what is better approach and professional way to do this. Thank you.
Here you go >>>>In models.py
class Category(models.Model):
name = models.CharField(max_length=50, null=True, blank=True, unique=True)
class Product(models.Model):
name = models.CharField(max_length=80, null=True, blank=True, unique=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True)
In your views.py::
def myView(request):
my_list = []
all_prd = Product.objects.all()
all_cat = Category.objects.all()
for cat in all_cat:
temp = list(all_prd.objects.filter(category__name = cat ))
my_list.append(temp)
my_list = list(filter(None, my_list)
context = [
'my_list' : my_list,
]
return(request, 'cute.html' , context)
In cute.html ::
<ul>
{% for item in my_list %}
{% for prd in item %}
{{prd.name}}
{% endfor %}
<br>
<br>
{% endfor %}
</ul>
I gave you a hint.modify it like you want.
Related
My objective is to iterate through the model DeathDay posts that can be created through the admin (which contain several names and surnames) and display the last three persons that have been registered in such a model in the homepage that correspond to today. At the moment, I'm using a ListView function and it allows me to paste every name and surname that have been registered today. However, I tried to use the slice method but in such a case it finds that the first three elements of the list have no been created today and it does not show any result on my template.
Template:
{% for post in object_list %}
{% if date == post.daytoday %}
<b>{{ post.daynome }} {{ post.daycognome }}</b> </br>
{% endif %}
{% endfor %}
Models.py:
class DeathDay(models.Model):
daynome = models.CharField(max_length=120, blank=True)
daycognome = models.CharField(max_length=120, blank=True)
daynascita = models.DateField(max_length=120, blank=True)
daymorte = models.DateField(null=True, blank=True)
daytoday = models.DateField(auto_now_add=True)
dayluogo = models.CharField(max_length=120, null=True, blank=True)
object_list = List.objects.last()
gives you the last object created
I have parent class and child class, that inherits parent class. And that is okay, I can iterate with for loop. Now I want to access child class (example: 'product_type' So basically, I'm confused how we inherits stuff from child class inside the same loop...
views.py
from django.views import generic
from . models import Category
from django.shortcuts import render
class CategoryListView(generic.ListView):
model = Category
template_name = 'category_list.html'
models.py
from django.db import models
import uuid
class Category(models.Model):
name = models.CharField(max_length=100, help_text='Category name')
def __str__(self):
return self.name
class Meta:
verbose_name_plural = 'Categories'
class Product(models.Model):
product_name = models.CharField(max_length=255, help_text='Product name')
# product_spec = models.TextField(max_length=5000, help_text='Product specs')
product_type = models.ForeignKey('Category', on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.product_name
category_list.html
{% extends 'base.html' %}
{% block body %}
{% for page in category_list %}
<li>{{ page.name }}</li>
<li>{{ page.product_name }} # <--------------- Now this is the point of
#my problem, I want to get
#product name from child
#class
#this returns empty <li>
{% endfor %}
{% endblock %}
you can to this
{% extends 'base.html' %}
{% block body %}
{% for page in category_list %}
<li>{{ page.name }}</li>
<li>{{ page.product_set.first.product_name }}
product name from child class, this returns empty <li>
{% endfor %}
{% endblock %}
First off change your product_type name to just category its way easier to understand and add an attribute related_name to it like this:
class Product(models.Model):
name = models.CharField(max_length=255, help_text='Product name')
category = models.ForeignKey('Category', on_delete=models.SET_NULL, null=True, related_name='products')
then in your template
{% for category in category_list %}
{{ category.name }}
{% for product in category.products.all %}
{{ product.name}}
... other product data
{% endfor %}
{% endfior %}
product_typein Product is a ForaignKey which means their will be multiple products having same Category so their exist two solutions
make product_type in Product one to one key, with this you shuld get single name by {{ page.product.product_name }}
print list of all products of the category, you can do this by iterating page.product_set as it is a list (iterable) with for loop.
I'm trying to a menu system for my sport site project where the sports are grouped together. For example the main category would be "ballsports" and under that (the child menu) people would select football, baseball or whatever else. I've got that all setup and functioning but I can't workout how to call the child menus into the templates.
Models:
class Sport(models.Model):
name = models.CharField(max_length=100, db_index=True)
sport_slug = models.SlugField(max_length=100, db_index=True)
category = models.ForeignKey('Sport_Category', on_delete=models.CASCADE,)
class Sport_Category(models.Model):
name = models.CharField(max_length=100, db_index=True)
category_slug = models.SlugField(max_length=100, db_index=True)
Views:
class IndexView(generic.ListView):
template_name="sports/index.html"
context_object_name='all_sport_category'
def get_queryset(self):
return Sport_Category.objects.all()
def list_of_sports_in_category(self):
sport_cat = self.category.name
return sport_cat
class SportListView(generic.ListView):
template_name="sports/sport-home.html"
context_object_name='sport_list'
def get_queryset(self):
return Sport.objects.all()
Template:
{% for sport_category in all_sport_category %}
<li>{{ sport_category.name }} </li> *(Working)*
{% for sports in list_of_sports_in_category %}
hi
{% endfor %}
{% endfor %}
list_of_sports_in_category method seems to return the category name, rather than the list of sports. try replacing the second for-loop in your template with {% for sport in sport_list %}.
I am having some trouble getting the values from a snippet, that I have included into a streamfield using a Snippet Chooser Block.
BioSnippet:
#register_snippet
class BioSnippet(models.Model):
name = models.CharField(max_length=200, null=True)
job_title = models.CharField(max_length=200, null=True, blank=True)
bio = RichTextField(blank=True)
image = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
verbose_name='Bio Image'
)
contact_email = models.CharField(max_length=50, null=True, blank=True)
contact_phone = models.CharField(max_length=50, null=True, blank=True)
panels = [
FieldPanel('name'),
FieldPanel('job_title'),
FieldPanel('bio'),
ImageChooserPanel('image'),
FieldPanel('contact_email'),
FieldPanel('contact_phone'),
]
def __str__(self):
return self.name
class Meta:
ordering = ['name',]
Bio Streamfield Definitions:
class BioInline(StructBlock):
bio = SnippetChooserBlock(BioSnippet)
class BioBlock(StructBlock):
overall_title = CharBlock(required=False)
bios = ListBlock(BioInline())
This all works, but when I get to the template, I cannot seem to access the values of the snippet
{% for b in child.value.bios %}
{{ b }}
<hr>
{{ b.name }}
{% endfor %}
the {{ b }} tag outputs:
bio
Sales Team
However {{ b.name }} outputs nothing. Neither does {{ b.values.name }} or any other permutation I can guess at. I suspect the values are just not being pulled down.
bios here is defined as a list of BioInline values, and so b in your template would be a BioInline value - which has a single property, bio (giving you the actual BioSnippet object). To get the name, you'd therefore have to use: {{ b.bio.name }}.
I don't think the BioInline object is actually gaining you anything though - you could instead define BioBlock as:
class BioBlock(StructBlock):
overall_title = CharBlock(required=False)
bios = ListBlock(SnippetChooserBlock(BioSnippet))
which would make bios a list of BioSnippets - {{ b.name }} would then work as expected.
Alternatively, you can use self.bios
In blocks.py you have to import the Snippet model (should have this allready):
from thebioapp.models import BioSnippet
And then use this model in the template itself
{% for b in self.bios %}
{{ b }}
<hr>
{{ b.name }}
{% endfor %}
The post is old, but as Wagtail is growing in popularity, I hope this will benefit others!
I have two models news and category, and in news I have foreignkey of category. I know how to display news with same category in a single template. but furthermore, in my home page I'm trying to display featured news of each category. this is where I'm having problem.
this is my models.py
class News(models.Model):
title = models.CharField(max_length=120)
content = models.TextField()
category = models.ForeignKey("Tag")
active = models.BooleanField(default=True)
featured = models.BooleanField(default=False)
top = models.BooleanField(default=False)
slug = models.CharField(max_length=255, unique=True)
featuredInCat = models.BooleanField(default=False)
objects = StoryManager()
class NewsQueryset(models.query.QuerySet):
def active(self):
return self.filter(active=True)
def featuredInCat(self):
return self.filter(featuredInCat=True)
class NewsManager(models.Manager):
def get_queryset(self):
return NewsQueryset(self.model, using=self._db)
def get_featuredInCat(self):
return self.get_queryset().active().featuredInCat()
def all(self):
return self.get_queryset().active()
class Category(models.Model):
title = models.CharField(max_length=120)
description = models.TextField(max_length=5000, null=True, blank=True)
In views.py
def category_list(request):
categoryList = NewsCategory.objects.all()
featuredInCat = News.objects.get_featuredInCat()
context = {
"featuredInCat":featuredInCat
"categoryList":categoryList,
}
return render(request,"news/category_list.html", context)
In my template
{% for category in categoryList %}
<div class='col-sm-4'>
<div id="container">{{category.title}}</h1>
<ul>
{% for x in featuredInCat %}
{{x.title}}</li>
{% endfor %}
</ul>
</div>
<hr>
</div>
{% endfor %}
then this shows the featuredInCat in every category where featuredInCat should be shown only in its Category section.
how do I fix this?
Take a look at the built-in regroup template tag of django. You will need to change your template to something like this:
{% regroup featuredInCat by category as news_list %}
<ul>
{% for news in news_list %}
<li>{{ news.grouper.title }}
<ul>
{% for item in news.list %}
<li>{{ item.title }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
You can change your for loop to iterate over the correct objects
{% for x in category.news_set.get_featuredInCat %}
You won't need the context variable anymore