Here my problem, The user can add Sections, in the section he can add documents, what I would like to do it's to return all documents added in section I can't figure it out which way is the best to filter by section:
Here my model for the Documents :
class Document(models.Model):
"""
Staff of the hospital center services
"""
# ATTRIBUTES
label = models.CharField(
max_length=255,
verbose_name='Intitulé'
)
description = models.TextField(
verbose_name='Description',
blank=True,
null=True
)
document = models.FileField(
verbose_name='Document'
)
section = models.ForeignKey(
'espace_documentaire.EspaceDocumentaire',
verbose_name="Espace Documentaire",
related_name="documents",
null=True,
blank=True,
on_delete=models.CASCADE
)
dedicated_page = models.ForeignKey(
"pages.Pages",
verbose_name="Page",
related_name="documents",
null=True,
blank=True,
on_delete=models.CASCADE
)
division = models.ForeignKey(
"services.Division",
verbose_name="Pôle",
related_name="documents",
null=True,
blank=True,
on_delete=models.CASCADE
)
order = models.IntegerField(
verbose_name="Ordre d'affichage",
default=0
)
# TRACE
date_created = models.DateTimeField(
verbose_name="date de création",
auto_now=True
)
date_updated = models.DateTimeField(
verbose_name="date de modification",
auto_now=True
)
def __str__(self):
return self.section
Here my Model for the Sections :
class EspaceDocumentaire(models.Model):
# ATTRIBUTES
section = models.CharField(
max_length=255,
verbose_name='Nom de la section'
)
colorsection = models.CharField(
max_length=255,
verbose_name='Couleur de la section'
)
order = models.IntegerField(
verbose_name="Ordre d'affichage",
default=0
)
document = models.ForeignKey(
'documents.Document',
verbose_name="Document",
related_name="documents",
null=True,
blank=True,
on_delete=models.CASCADE
)
def __str__(self):
return self.section
Here my template :
{% for ed in espace_documentaire %}
<div class="dpt-toggle" id="{{ ed.pk }}">
<h3 class="toggle-title">{{ed.section}}</h3>
<div class="toggle-content">
<div class="tabs clearfix">
{% for document in documents %}
{% if document.section == ed.section %}
<h1>{{ document.label }}</h1>
{% endif %}
{% endfor %}
</div>
</div>
</div>
{% endfor %}
Thanks
Here is how you would filter a single section documents in a view:
def section_documents(request, pk):
section = EspaceDocumentaire.objects.get(pk=pk)
documents = section.documents.all() # using related name you set in your model
return render(request, 'section_documents.html', {'section': section, 'documents': documents})
Then in your template:
{% for document in documents %}
{{ document }}
{% endfor %}
OR you could also just use the related name in the template like this:
def sections_and_documents(request):
sections = EspaceDocumentaire.objects.all()
return render(request, 'sections_and_documents.html', {'sections': sections)
and in the template:
{% for section in sections %}
{{ section }}
{% for document in section.documents.all %}
{{ document }}
{% endfor %}
{% endfor %}
Related
I am using the following ModelForm:
class ListingQuoteForm(forms.ModelForm):
author_phone = forms.CharField(validators=[validate_phone_number])
content = forms.CharField(
label='Your message',
min_length=50,
widget=forms.Textarea(attrs={'rows': 4}),
help_text='Please provide a few details about your race and your requirements',
)
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if user.is_authenticated:
self.fields['author_name'].initial = user.full_name(strict=True)
self.fields['author_email'].initial = user.email
self.fields['author_email'].disabled = True
class Meta:
model = QuoteRequest
fields = ('author_name', 'author_email', 'author_phone', 'content')
labels = {
'author_name': 'Your name',
'author_email': 'Your email',
'author_phone': 'Your phone number',
}
and rendering it in the following template:
{% load crispy_forms_tags %}
<div class="listing-section" id="quote-form">
<div class="listing-section-header">
{% if primary_category.quote_request_type == 'quote' %}
<h2>Request a quote</h2>
{% elif primary_category.quote_request_type == 'info' %}
<h2>Request more info</h2>
{% endif %}
</div>
<div class="listing-section-body">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ quote_form.author_name|as_crispy_field }}
{{ quote_form.author_email|as_crispy_field }}
{{ quote_form.author_phone|as_crispy_field }}
{{ quote_form.content|as_crispy_field }}
<div class="form-group">
<button class="standard-button standard-button--submit" type="submit">Send</button>
</div>
</form>
</div>
</div>
When the content field min length validation fails, a message is displayed like so:
But when my custom phone number validation fails, the error displays under the field like so:
EDIT: Here's the QuoteRequest object as well:
class QuoteRequest(models.Model, ModelMixin):
SOURCES = (
('listing_page', 'Listing page'),
('dashboard_offers', 'Dashboard offers'),
('concierge', 'Concierge'),
)
source = models.CharField(max_length=18, null=True, blank=True, choices=SOURCES)
author = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL, related_name='quote_requests')
author_name = models.CharField(max_length=40)
author_email = models.EmailField()
author_phone = models.CharField(max_length=24, null=True, blank=True, validators=[validate_phone_number])
content = models.TextField()
category = models.ForeignKey(Category, null=True, blank=True, on_delete=models.CASCADE, related_name='quote_requests')
listing = models.ForeignKey(Listing, null=True, blank=True, on_delete=models.CASCADE, related_name='quote_requests')
offer = models.ForeignKey(Offer, null=True, blank=True, on_delete=models.SET_NULL, related_name='quote_requests')
race = models.ForeignKey(Race, null=True, blank=True, on_delete=models.SET_NULL, related_name='quote_requests')
approved = models.BooleanField(default=False)
date_created = models.DateTimeField(auto_now_add=True)
date_approved = models.DateTimeField(null=True)
How can I get my phone number validation error to display the same way the in-built min length validation does for the CharField?
You can use novalidate on form, to off default behavior of html5 of showing errors so that Django's errors can be shown.
So:
<form method="POST" enctype="multipart/form-data" novalidate>
{% csrf_token %}
{{ quote_form.author_name|as_crispy_field }}
{{ quote_form.author_email|as_crispy_field }}
{{ quote_form.author_phone|as_crispy_field }}
{{ quote_form.content|as_crispy_field }}
<div class="form-group">
<button class="standard-button standard-button--submit" type="submit">Send</button>
</div>
</form>
I have 3 models and I need to display the area and need items only if there is at least 1 product connected. If there are no products in particular Area and Need models then it should not appear in my HTML file.
I have checked the documentation and several answers related to this topic but I cannot implement it in my script.
I also tried to create my custom filter so I can apply it directly in my template but nothing worked.
My problem is that I am getting the list of all items from Need model and I don't know how to exclude empty items from HTML page.
I will appreciate any help.
models.py
class Area(models.Model):
title = models.CharField(max_length=75, blank=False)
body = models.CharField(max_length=150, default='-', blank=False)
publish = models.DateTimeField('publish', default=timezone.now)
class Need(models.Model):
title = models.CharField(max_length=75, blank=False, null=False, help_text='max 75 characters')
body = models.CharField(max_length=150, default='-', blank=False)
publish = models.DateTimeField(default=timezone.now)
need_area = models.ForeignKey(Area, on_delete=models.CASCADE, related_name='need_area')
class ProductCategory(models.Model):
title = models.CharField(max_length=400, blank=False, null=False, help_text='max 400 characters')
body = models.TextField(default='-')
publish = models.DateTimeField('publish', default=timezone.now)
category_area = models.ForeignKey(Area, on_delete=models.CASCADE, related_name='category_area', null=True)
category_need = models.ForeignKey(Need, on_delete=models.CASCADE, related_name='category_need', null=True)
class Product(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=400, blank=False)
category = models.ForeignKey(ProductCategory, on_delete = models.CASCADE, blank=True, related_name='products')
status = models.IntegerField(choices=STATUS, default=0)
def get_absolute_url(self):
return reverse("product", kwargs={'slug': self.slug})
views.py
class Search(ListView):
template_name = 'search.html'
model = Product
queryset = Product.objects.filter(status=1)
def get_context_data(self, **kwargs):
context = super(Search, self).get_context_data(**kwargs)
filter_need = Area.objects.filter(Exists(Need.objects.filter(need_area=OuterRef('pk'))))
areas = Area.objects.prefetch_related(Prefetch('need_area', queryset=filter_need, to_attr='need_area__category_need__product')).filter(need_area__category_need__product__status=1).distinct()
context['areas'] = areas
return context
search.html
{% if areas %}
{% for area in areas %}
<div class="border mb-4 pb-4 px-2">
<h2 class="fw-bold my-2">{{area.title}}</h2>
{% for need in area.need_area.all %}
<h4 class="text-muted mt-4">{{need.title}}:</h4>
{% for product_category in need.category_need.all %}
{% for product in product_category.product.all %}
<span class="rounded-pill bg-hubble text-dark f-12 p-2">{{product.title}}</span>
{% endfor %}
{% endfor %}
{% endfor %}
</div>
{% endfor %}
{% endif %}
I'm new to Django. i'm trying to display all the comments for a listing in an auction site
Help me find a way to display all the comments for a listing.
Mosdels.py
class Listing(models.Model):
title = models.CharField(max_length=64, default="")
starting_bid = models.CharField(max_length=64, default="$")
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, default="")
def __str__(self):
return self.title
class Comment(models.Model):
comment = models.TextField(default="")
listing = models.ForeignKey(Listing, on_delete=models.CASCADE, related_name="comments", default="")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="comments", default="")
def __str__(self):
return f"{self.user} - {self.listing}"
views.py
def listing(request, listing_id):
listing = Listing.objects.get(pk=listing_id)
comments = listing.comments.all()
return render(request, "auctions/listing.html", {
"listing":listing,
"comments":comments
})
_If you are trying to display in a template you can use something like following:
{% for listing_item in listing %}
<div>{{listing_item.title}}
{% for comment in listing_item.comment_set.all %}
<div>{{comment}}</div>
{% endfor %}
</div>
{% endfor %}
EDIT: If only sending the one listing from your view:
{{listing.title}}
{% for comment in listing.comment_set.all %}
<div>{{comment}}</div>
{% endfor %}
EDIT2: Noticed you have a related name there.
{{listing.title}}
{% for comment in listing.comments.all %}
<div>{{comment}}</div>
{% endfor %}
I am rendering a ManyToManyField in my template but it is shown like this :
<QuerySet [<User: Guido>]>
And I just want to print out the username without the function.
My views.py
class HotelListView(LoginRequiredMixin,ListView):
model = Hotel
def get_queryset(self):
return self.model.objects.filter(collaborateurs=self.request.user)
My template
{% for Hotel in object_list %}
{{ Hotel.collaborateurs.ALL }}
{% endfor %}
Thanks.
Edit
Models.py
class Hotel(models.Model):
collaborateurs = models.ManyToManyField(User, verbose_name="Liste des collaborateurs autorisés")
code = models.CharField(max_length=500,verbose_name="Code hôtel", null=True, blank=True)
email_manager = models.EmailField(max_length=150,verbose_name="Contact RH", null=True, blank=True)
contact_rh = models.EmailField(max_length=150,verbose_name="Contact RH", null=True, blank=True)
contact_gm = models.EmailField(max_length=150,verbose_name="Contact GM",null=True, blank=True)
payday = models.CharField(max_length=500,verbose_name="Jour de paye prévu du mois", null=True, blank=True)
hotel = models.CharField(max_length=500,verbose_name="Nom de l'hôtel")
planning = models.URLField(max_length=500, verbose_name="Planning du mois", null=True, blank=True)
def __str__(self):
return self.hotel
def get_absolute_url(self):
return reverse('hotel')
You need to iterate through the collaborators as well.
{% for Hotel in object_list %}
{% for collaborator in Hotel.collaborateurs.all %}
{{ collaborator.name }}
{% endfor %}
{% endfor %}
(Obviously replace name with the relevant field from the model.)
How can i render my variables from models in a html file, they was rendering a time ago before I made html link slug with class(DetailView) in my views.py
HTML FILE (product.html)
<h2 class="heading">{{ product.name }}</h2>
<div style="clear: both;"><br></div>
<div class="block">
<div class="img_preview">
<img src="{{ product.img }}">
<div class="categ">
{% for category in product.category.all %}
<span>{{ category }}</span>
{% endfor %}
{# <div style="clear: both"><br></div> #}
</div>
</div>
<div id="links">
{% for link in links %}
<div class="download_link">
<span>DOWNLOAD MIRROR NUMBER {{ links.number }}</span>
</div>
{% endfor %}
</div>
<div style="clear: both"></div>
<div id="games">
<div id="video_trailer">
<iframe width="560" height="317" src="{{ product.video_trailer }}" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe>
<div id="description">
<span class="title">Description</span>
<p>{{ product.description }}</p>
</div>
</div>
<div style="clear: both"><br></div>
<div id="system_requirements">
<span class="title">System Requirements</span><br>
<p>Processor: {{ product.processor }}<br>
<br>
Graphic Card: {{ product.video }}<br>
<br>
Memory: {{ product.ram }}<br>
<br>
Disk Space: {{ product.disk_space }}<br>
<br>
OS: {{ product.oS }}
</p>
</div>
</div>
<div id="screenshots">
{% for image in product_images %}
<div class="screenshot">
<img width="1920px" height="1080px" src="{{ image.image }}" >
</div>
{% endfor %}
</div>
</div>
</div>
<aside>
<div id="news">
<h2 class="heading">News</h2>
<div style="clear: both"><br></div>
{% for articles in news_articles %}
<div id="articles">
<div class="article">
<a href="{{ articles.article.get_absolute_url }}">
<img src="{{ articles.image }}">
<div style="clear: both"></div>
<span></span><div style="clear: both"></div>
</a>
<em>{{ articles.article.created }}</em>
views.py
from django.shortcuts import render
from products.models import *
from news.models import *
from django.shortcuts import get_object_or_404
from django.views.generic.detail import DetailView
class GameLink(DetailView):
# model = Product
# context_object_name = 'product'
def get_object(self):
return get_object_or_404(Product, slug__iexact=self.kwargs['slug'])
class ArticleLink(DetailView):
model = Article
context_object_name = 'article'
def get_object(self):
return get_object_or_404(Article, slug__iexact=self.kwargs['slug'])
def product(request, product_id):
product = Product.objects.get(id=product_id)
product_images = ProductImage.objects.filter(is_active=True, is_main=False, id=product_id)
links = ProductDownload.objects.filter(is_active=True, product=product_id)
news_articles = NewsImage.objects.filter(is_active=True, is_main=True)
return render(request, 'products/product.html', locals())
urls.py
from django.contrib import admin
from django.conf.urls import *
from products import views
from products.views import *
urlpatterns = [
# url(r'^games/(?P<product_id>\w+)/$', views.product, name='product'),
url(r'^games/(?P<slug>[-\w]+)/$', GameLink.as_view(template_name = 'products/product.html'), name='product'),
url(r'^articles/(?P<slug>[-\w]+)/$', ArticleLink.as_view(template_name = 'news/article.html'), name='article')
]
models.py
`
from django.db import models
from django.urls import reverse
class ProductCategory(models.Model):
name = models.CharField(max_length=128, blank=True, null=True, default=None)
is_active = models.BooleanField(default=True)
def __str__(self):
return '%s' % self.name
class Meta:
verbose_name = 'Category'
verbose_name_plural = 'Categories'
class Product(models.Model):
name = models.CharField(max_length=128, blank=True, null=True, default=None)
description = models.TextField(default=None)
processor = models.CharField(max_length=300, blank=True, null=True, default=None)
video = models.CharField(max_length=300, blank=True, null=True, default=None)
ram = models.CharField(max_length=300, blank=True, null=True, default=None)
disk_space = models.CharField(max_length=300, blank=True, null=True, default=None)
oS = models.CharField(max_length=300, blank=True, null=True, default=None)
video_trailer = models.CharField(max_length=10000, blank=True, null=True, default=None)
img = models.CharField(max_length=10000, blank=True, null=True, default=None)
category = models.ManyToManyField(ProductCategory, blank=True, default=None)
is_active = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
slug = models.SlugField(primary_key=True, max_length=250, unique=True, default=None)
def __str__(self):
return '%s' % self.name
def get_absolute_url(self):
return reverse('product', args=[str(self.slug)])
class Meta:
verbose_name = 'Game'
verbose_name_plural = 'Games'
class ProductDownload(models.Model):
product = models.ForeignKey(Product, blank=True, null=True, default=None, on_delete=False)
link = models.CharField(max_length=10000, blank=True, null=True, default=None)
is_active = models.BooleanField(default=True)
number = models.PositiveIntegerField(blank=True, default=True)
def __str__(self):
return '%s' % self.product.name
class Meta:
ordering = ['number']
class Meta:
verbose_name = 'Download Link'
verbose_name_plural = 'Download Links'
class ProductImage(models.Model):
product = models.ForeignKey(Product, blank=True, null=True, default=None, on_delete=False)
image = models.CharField(max_length=10000, blank=True, null=True, default=None)
is_main = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
def __str__(self):
return '%s' % self.product
class Meta:
verbose_name = 'Image'
verbose_name_plural = 'Images'
HTML file show only Product variables that are called with {{ product.___ }} but doesn't renders the rest like my links called with :
{% for link in links %}
{{ link.link }}
{% endfor %}
or like my articles...
How should I proceed to render on my page needed models.
Image of file paths
here
There are different forms to add adicional 'variables' using a DetailView (link)
For example:
class GameLink(DetailView):
def get_object(self):
return get_object_or_404(Product, slug__iexact=self.kwargs['slug'])
def links(self):
return ProductDownload.objects.filter(is_active=True, product=self.object)
And in product.html:
{% for link in view.links %}
<div class="download_link">
<span>DOWNLOAD MIRROR NUMBER {{ links.number }}</span>
</div>
{% endfor %}
IF you don't want to change HTML, instead of declaring the "def links(self)":
class GameLink(DetailView):
def get_object(self):
return get_object_or_404(Product, slug__iexact=self.kwargs['slug'])
def get_context_data(self, **kwargs):
context = super(GameLink, self).get_context_data(**kwargs)
context['links'] = ProductDownload.objects.filter(is_active=True, product=self.object)
return context