Trying to get the table name in django, I need it to display the detailview correctly via if statemnet.
I have such a view to display
class Home(ListView):
template_name = 'home.html'
def get_queryset(self):
qs1 = Book.objects.all()
qs2 = CD.objects.all()
qs3 = Film.objects.all()
queryset = sorted(list(chain(qs1, qs2, qs3)), key=operator.attrgetter('title'))
return queryset
and it returns to me this
[<CD: Music1>, <CD: Music2>, <Book: Some books>]
How can I get "CD" or "Book" in this template
{% block content %}
<div class="row">
{% for object in object_list %}
<div class="col-md-3">
<div class="card card-product-grid">
<img src="{{ object.image.url }}">
{{ object.title }}
</div>
</div>
{% endfor %}
</div>
{% endblock content %}
At the same time, if it's a bad idea to display detailview and listview and it's done differently, I'd appreciate it if you'd let me know
I tried different ways of displaying object.key in a loop but it didn't work very well. And other queryset queries.
I've been down the list(chain(ob1, ob2, .. obn) route. It proved highly tedious from a standpoint of code maintainability and complexity. Django Polymorphic is the way to go here.
from polymorphic.models import PolymorphicModel
class Product(PolymorphicModel):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='products')
title = models.CharField(max_length=100)
slug = ...
... more fields all products share ex: price
def __str__(self):
return str(self.title)
#property
def model_name(self):
return self._meta.model_name
class Cd(Product):
<model fields for CD model>
class Book(Product):
<model fields for book model>
class Film(Product):
<model fields for film model>
Then:
Product.objects.all()
Will return the instances of all CD, Book and Film objects.
In your template, you can use the property model_name to check if the object is a certain type of model.
{% block content %}
<div class="row">
{% for object in object_list %}
{% if object.model_name == 'book' %}
<div class="col-md-3">
<div class="card card-product-grid">
<img src="{{ object.image.url }}">
{{ object.title }}
</div>
</div>
{% endif %}
{% endfor %}
</div>
{% endblock content %}
You can obtain this with the .verbose_name attribute [Django-doc] of the model options, so my_object._meta.verbose_name. There is however a problem here: you can not access variables that start with an underscore, since these are "protected" or "private".
A solution might be to work with a template filter. You can define a templatetags directory:
app_name/
__init__.py
models.py
templatetags/
__init__.py
model_utils.py
views.py
where you create the files in boldface. In model_utils, you can construct a filter with:
from django import template
register = template.Library()
#register.filter
def modelname(value):
return value._meta.verbose_name
then we can use these in the template with:
{% load model_utils %}
{% for object in object_list %}
…
{{ object|modelname }}
{% endfor %}
Related
hello iam trying to make Dropdown Menu in Navbar with querysets. I was trying to make it with two querysets send to html template ( "stages","questions") that are related to each other by key (id , stage_id), but i cant figured out why forloops cant work together. My second try was with passing data in json to javascript and make it with js QuerySelector, but django querysets are not JSON serializable. Any suggestions how to make it please ?
views.py
def edit_pages(request, gameid):
stages = Stage.objects.filter(game_id=gameid)
print(stages)
questions = []
for st in stages:
questions = chain(questions,Question.objects.filter(stage_id=st.id))
print(questions)
return render(request, "homeSuperuser/edit_pages.html",{'stages': stages, 'questions': questions})
html
<body>
<div class="topnav">
{% for st in stages %}
<div class="dropdown">
<button class="dropbtn">{{st.stage_name}}</button>
<div class="dropdown-content">
{% for qs in questions %}
{% if qs.stage_id == st.id %}
{{qs.question_name}}
{% endif %}
{% endfor %}
</div>
</div>
{% endfor %}
</div>
</body>
Define a model method as follows
class Stage(models.Model):
name = models.CharField(max_length=128)
def get_questions(self):
return Question.objects.filter(stage=self)
def __str__(self):
return str(self.name)
class Question(models.Model):
stage = models.ForeignKey(Stage, on_delete=models.PROTECT, related_name="questions")
name = models.CharField(max_length=128)
def __str__(self):
return str(self.name)
Now you can loop them in the template as follows
{% for st in stages %}
<div class="dropdown">
<button class="dropbtn">{{st.name}}</button>
<div class="dropdown-content">
{% for qs in st.get_questions %}
{{qs.name}}
{% endfor %}
</div>
</div>
{% endfor %}
I have a model called Section and a model called SectionInfo. Section has one field and that's name. A user will create a section by giving it a name. SectionInfo has a foreign key section_name which links it to the Section model. I have a few other fields inside SectionInfo such as things like detail, date_created, etc. What I am trying to accomplish here is using a for loop to display section names that have already been created inside or above some cards that I have set up in an html template. Then I want to use a nested loop to gather the data that is tied to that section name which is what the user inputs in for the SectionInfo model. I am able to display the section names correctly, but the issue im having is in the loop inside that loop. The same detail link is being displayed in every section that was made. Information should only be displayed in the chosen section for which it was made.
Here is a bit of code to help you understand what I am trying to accomplish.
Template file:
{% extends "base.html" %}
{% load bootstrap5 %}
{% load crispy_forms_tags %}
{% load static %}
{% block content %}
{% for i in object %}
{{ i.name}}
<div class="row">
<div class="col-sm-4">
<div class="card">
<div class="card-body">
{% for ii in object_2 %}
Details
{% endfor %}
</div>
</div>
</div>
</div>
{% endfor %}
{% endblock content %}
Here is what I am getting displayed
whats being displayed
Here is the view that's being used
def section_info_detail(request, pk):
object = get_object_or_404(Section, id=pk)
object_2 = get_object_or_404(SectionInfo, id=pk)
context = {
'object': object,
'object_2':object_2,
}
return render(request, 'manufacturing/section_info_detail.html', context)
Models.py:
class Section(models.Model):
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class SectionInfo(models.Model):
section_name = models.ForeignKey(Section, on_delete=models.CASCADE)
detail = models.CharField(max_length=50)
text = models.TextField(max_length=2000)
date_created = models.DateField('Date created', auto_now_add=True)
date_updated = models.DateField('Date updated', auto_now=True)
Forms.py:
class SectionNameForm(forms.ModelForm):
class Meta:
model = Section
fields = [
'name',
]
class SectionInfoForm(forms.ModelForm):
class Meta:
model = SectionInfo
fields = [
'section_name',
'detail',
'text',
]
If any other information is needed, do tell.
<div class="row">
{% for object in object_list %}
<div class="col-sm-4">
<div class="card">
<div class="card-header">
<h1><strong>{{ object.name }}</strong></h1>
<hr>
</div>
<div class="card-body">
<div class="row">
{% for info in object.section_infos.all %}
<ul id="list">
<li>{{ info.date_created }}</li> |
<li>{{ info.detail|truncatechars:20 }}</li>
<hr>
</ul>
{% endfor %}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
This did it for me. So basically what my problem was I was not drilling down far enough to get the data that I needed to be displayed from the template. Also I had changed some things up in my models and had created a manyTomany and through field
I want to display 1 Parent Field with associated Child and further there Childs
I have a Model
class GrandParent(models.Model):
name= models.CharField(max_length=50)
....
class Parent(models.Model):
parent = models.ForeignKey(GrandParent, on_delete=models.CASCADE)
name= models.CharField(max_length=50)
....
class Child(models.Models):
parent = models.ForeignKey(Parent, on_delete=models.CASCADE)
name= models.CharField(max_length=50)
...
I am able to render objects from Grand Parent But I m unable to link further Parent Class objects and Child class objects in templates
This approach I used in views.py
def list(request):
object_list = GrandParent.published.all()
...
return render('app/list.html')
def detail(request, post,):
post = get_object_or_404(GrandParent, slug=post,
status='published')
return render(request, 'app/detail.html',
{'post' : post,
...
})
Now how to link further Classes in Same Detail View But Associated with there Parent Classes using Foreign Key. I'm following Django docs but they only giving max 2 examples using python shell with just One subclass I m confused How to implement there in this structure. Or anyone have already developed any project specifically with this type of models so please share any link of repo or something, would be wonderful.
#list.html
{% extends "_base.html" %}
{% block title %} mysite{% endblock %}
{% block content %}
<h2>Content </h2>
<ul>
{% for post in object_list %}
<a href="{{ post.get_absolute_url }}">
<li>{{ post.name}}</li></a>
{% endfor %}
</ul>
{% endblock %}
#detail.html
{% extends "_base.html" %}
{% block title %} freeStreams {% endblock %}
{% block content %}
<div class="card-body">
<h1 class="card-title">{{ post.title }}</h1>
</div>
{% endblock %}
You can access from one to many in view template by for loop all child of it. In your case, with GrandParent by post.parent_set.all(). For Child by parent.child_set.all(). You can try first in terminal for check you have correct database and relation.
Add it inside block content
detail.html
{% for parent in post.parent_set.all() %}
<h1 class="card-title">{{ parent.name }}</h1>
{% for child in parent.child_set.all() %}
<h2 class="card-title">{{ child.name }}</h2>
{% endfor %}
{% endfor %}
I am using django-filter==2.1.0 for implementing search filter. I already implement it. But now i need to search by clicking checkbox not by search button. My codes are given below:
models.py
class Book(models.Model):
name = models.CharField(max_length=100)
publication = models.ForeignKey(Publication, on_delete=models.CASCADE)
filters.py
class BookFilter(django_filters.FilterSet):
publication = django_filters.ModelMultipleChoiceFilter(queryset=Publication.objects.all(),
widget= forms.CheckboxSelectMultiple)
class Meta:
model = Book
fields = ['publication']
views.py
def test_view(request):
book_list = Book.objects.all()
book_filter = BookFilter(request.GET, queryset=book_list)
temp = book_filter.form
return render(request, 'test.html', {'filter': book_filter})
template
{% extends 'base.html' %}
{% load widget_tweaks %}
{% block content %}
<form method="get">
{% for choice in filter.form.publication %}
<label>
{{ choice.tag }}
<span class="max-content-width">{{ choice.choice_label }}</span>
</label>
{% endfor %}
<button type="submit">Search</button>
</form>
<ul>
{% for book in filter.qs %}
<li>{{ book.name }}</li>
{% endfor %}
</ul>
{% endblock %}
It's working properly. But i want to add widget = forms.CheckboxInput(attrs={'onclick': 'this.form.submit();'}) in my filters.py for checkbox input. I don't understand how can i add another widget. Please help me to solve this problem.
Create a widget, write JavaScript script and use Media metaclass on widget to use it. After this just use your widget on your checkbox field.
I use a generic view to list my categories.
I would also like to display the title of each items belonging to these categories.
I understand the principle of ListView and DetailView but what about some details in lists ?
Here are my different files:
Models.py
class categories(models.Model):
name = models.CharField(max_length=50,unique=True)
slug = models.SlugField(max_length=100,unique=True)
def __str__(self):
return self.name
class details(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=42)
category = models.ForeignKey('categories', on_delete=models.CASCADE)
def __str__(self):
return self.title
Views.py
class IndexView(generic.ListView):
model = categories
context_object_name = "list_categories"
template_name='show/index.html'
Urls.py
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
]
Index.html
{% load static %}
<p>These is a list of categories</p>
{% for category in list_categories %}
<div class="article">
<h3>{{ category.name }}</h3>
{% for title in category.detail %}
<p> {{title}} </p>
{% endfor %}
</div>
{% endfor %}
You need to first reverse call the details with related name i.e "categories".
{% load staticfiles %}
<p>These is a list of categories</p>
{% for category in list_categories %}
<div class="article">
<h3>{{ category.name }}</h3>
{% for detail in category.categories.all %}
<p> {{detail.title}} </p>
{% endfor %}
</div>
Be careful you must use all after reverse all because there could be more then one reverse relation.
Still have any doubts comment it below.