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
Related
Models.py
class Listing(models.Model):
title = models.CharField(max_length=64, default="")
bid = models.ForeignKey(Bid, on_delete=models.CASCADE, related_name="listing", default=None,)
description = models.TextField(default="")
image_url = models.CharField(max_length=200, default="")
date = models.DateTimeField(default=timezone.now)
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="listings", default="")
is_closed = models.BooleanField(default=False, blank=True, null=True)
watchlist = models.ManyToManyField(User, blank=True, related_name="watching")
owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="listing", null=False, blank=True, default="")
def __str__(self):
return self.title
#the category class
class Category(models.Model):
category = models.CharField(max_length=64)
def __str__(self):
return self.category
Views.py
*This is where I think the problem is because i'm not very familiar with the methods, if I use category = request.POST["category], I get an error saying multivalue dict..., I'm just stuck here if you have a clue how i can modify this method to show the items in a category *
def categories(request):
category = request.POST("category")
listings = category.listings.all()
return render(request, "auctions/categories.html", { "listings":listings })
```
categories.html
{% extends "auctions/layout.html" %}
{% block body %}
<h2>Categories</h2>
<form action="{% url 'categories' %}" method="post">
<div class="form-group">
<label for="categories">Category</label>
<select class="form-control" name="categories" id="categories">
{% for category in categories %}
<option>{{category}}</option>
{% endfor %}
</select>
</div>
</form>
{% for listing in listings %}
{% if not listing.is_closed or user == listing.bid.user %}
<p></p>
<div class="card" style="width: 60rem;">
<img class="card-img-top" style="width: 20rem;" src="{{listing.image_url}}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{listing.title}}</h5>
<p class="card-text">{{listing.description}}</p>
<p>Bid: {{listing.bid}}</p>
<p>Created {{listing.date}}</p>
</div>
<div class="card-body">
More
</div>
</div>
<p></p>
{% endif %}
{% endfor %}
{% endblock %}
You're not receiving anything as POST, so there wouldn't be any value there.
Your lines of:
category = request.POST("category")
listings = category.listings.all()
make no sense because:
in category = request.POST("category") you are first trying to store something into category from the POST which #1 doesn't exist and #2 would be a string even if it did.
Let's just assume there is something in the POST with the key "category", you then try to receive all the listings using the category variable. Since you didn't define category variable properly, there's no way this would work anyways. Assuming for one second that you had, the Category object you defined in your models has no listings field or relation.
The correct way to do this would be:
category = Category.objects.get(category="Name Of Category You Set")
listings = Listing.objects.filter(category=category)
But before you go ahead and do anything, I really recommend you learn more about Objects and classes because seeing your above attempts you seem to lack knowledge of not only those but of variables swell.
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.
I'm working in Django 2.2 trying to build a view for a database that compiles everything for a specific company (locations of all of their stores and notes on the companies) into a single view. I've tried methods in several different answers, but still cannot seem to get data from related foreign keys to show in the template.
models.py
class Company(models.Model):
name = models.CharField(max_length=30, primary_key=True)
official_name = models.CharField(max_length=50)
corporate_address1 = models.CharField(max_length=50)
corporate_address2 = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.ForeignKey('Country', on_delete=models.CASCADE)
slug = models.SlugField(max_length=30, unique=True)
def __str__(self):
return self.name
class Stores(models.Model):
store_name = models.CharField(max_length=30, primary_key=True)
owner = models.ForeignKey('Company', on_delete=models.CASCADE)
store_address1 = models.CharField(max_length=50)
store_address2 = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.ForeignKey('Country', on_delete=models.CASCADE)
type = models.CharField(max_length=30,choices=store_types)
slug = models.SlugField(max_length=30, unique=True)
def get_absolute_url(self):
return reverse("store-detail", kwargs={"slug": self.slug})
class notes(models.Model):
title = models.CharField(max_length=120)
content = models.TextField()
posted = models.DateTimeField(db_index=True, auto_now_add=True)
category = models.ForeignKey('Company', on_delete=models.CASCADE)
active = models.BooleanField(default=True)
def get_absolute_url(self):
return reverse("article-detail", kwargs={"id": self.id})
class Country(models.Model):
country = models.CharField(max_length=30,choices=countries,primary_key=True)
class Meta:
ordering = ["-country"]
db_table = 'country'
def __str__(self):
return self.country
views.py
class CompanyOverView(LoginRequiredMixin, DetailView):
model = Company
template_name = "company-overview.html"
slug_url_kwarg = 'slug'
query_pk_and_slug = True
pk_url_kwarg = "company.name"
template
<div align="center">
<p>{{ object.name }}<br>({{ object.official_name }})</p>
<p>{{ object.corporate_address1 }}<br>{{ object.corporate_address2 }}<br>
{{ object.city }}<br>{{ object.state_province }}<br>
{{ object.country }}</p>
</div>
<p>List of Stores</p>
<p>
{% for instance in object_list %}
{{ instance.company.stores.store_name }}
{{ instance.company.stores.store_address1 }}
{{ instance.company.stores.store_address2 }}
{{ instance.company.stores.city }}
{{ instance.company.stores.state_province }}
{{ instance.company.stores.country }}
{% endfor %}
</p>
<p>Notes</p>
<p>
{% for instance in object_list %}
{{ instance.company.notes.title }}
{{ instance.company.notes.posted }}
{% endfor %}
</p>
With the above code, the only thing that appears when you enter in the company's name is everything at the top (e.g."object.name" appears on the page as "Acme Corporation"). Nothing in the for loop appears on the web page.
Looking at the documentation, object_list is the default name for context unless specified. I have tried different combinations such as "for store_name in company.store_set.all" and other combinations I found in other posts, but none have worked. I've combed the documentation for everything related to foreign keys, but can't find a solution that works.
Thanks in advance if you can help.
No. object_list is the default context name in a ListView. But you have a DetailView, and you already know what the default context name is for those because you're already using it: object. You just need to iterate over the reverse relation from there:
{% for store in object.stores_set.all %}
{{ store.store_name }}
{{ store.store_address1 }}
...
{% endfor %}
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!