I'm developing a new web app. I want to display data from the database to the html template. I don't get any errors but I don't get the data inside my views methode using 'Objects.all()'. When I tried the django shell it works.
I am using postgres database
enter image description here
#models.py
from django.db import models
from datetime import datetime
class Catégorie(models.Model):
désignation = models.CharField(max_length=200)
Description = models.TextField(blank=True)
Quantité_de_Stock = models.IntegerField()
photo_main = models.ImageField(upload_to='photos/%Y/%m/%d/')
est_publié = models.BooleanField(default=True)
date_de_modification = models.DateTimeField(default=datetime.now, blank=True)
def __str__(self):
return self.désignation
#views.py
from django.shortcuts import render
from .models import Catégorie
def index(request):
Catégorie_list=Catégorie.objects.all()
context = {
'Catégorie_list':Catégorie_list,
}
return render(request,'articles/Category.html',context)
#html
<div class="row">
{% if articles %}
{% for category in Catégorie_list %}
<div class="col-md-6 col-lg-4 mb-4">
<div class="card listing-preview">
<img class="card-img-top" src="{{ category.photo_main.url }}" alt="">
<div class="card-body">
<div class="listing-heading text-center">
<h4 class="text-primary" >{{ category.désignation }}</h4>
</div>
<hr>
Voir la catégorie
</div>
</div>
</div>
{% endfor %}
{% else %}
<div class="col-md-12">
<p>Aucune catégorie disponible</p>
</div>
{% endif %}
</div>
enter image description here
enter image description here
Related
My Problems are as follows:
Im relatively new to Django. so sorry for this mess.
I've tried to implement threaded comments to my blog via MPTT. But when i pressing the 'Reply' Button django throws me a Type Error
Normal parent comments working correctly
When i just create a comment with via the admin site, i can create parent comments and child comments and they will be indented just as expected in the main Application too...
my Database is mySQL.
The Error:
in _calculate_inter_tree_move_values
space_target = target_right - 1
~~~~~~~~~~~~~^~~
TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'
my models.py:
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from mptt.models import MPTTModel, TreeForeignKey
STATUS = (
(0,"Draft"),
(1,"Publish")
)
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete= models.CASCADE, related_name='blog_posts')
updated_on = models.DateTimeField(auto_now=True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post_detail',args=[self.slug])
class Comment(MPTTModel):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
name = models.CharField(max_length=80)
email = models.EmailField()
body = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=False)
parent=TreeForeignKey('self', null=True, blank=True, on_delete=models.CASCADE, related_name='children')
class MPTTMeta:
order_insertion_by = ['created_on',]
def __str__(self):
return 'Comment {} by {}'.format(self.body, self.name)
#just for the threaded comments
def get_comments(self):
return Comment.objects.filter(parent=self).filter(active=True)
views.py:
from django.shortcuts import render, get_object_or_404, redirect, HttpResponseRedirect
from django.views import generic
#from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
#from django.template import loader
from .models import Post, Comment
from .forms import CommentForm
class PostList(generic.ListView):
queryset = Post.objects.filter(status=1).order_by('-created_on')
template_name = 'index.html'
paginate_by = 3
#class PostDetail(generic.DetailView):
# model = Post
# template_name = 'post_detail.html'
class AboutMe(generic.TemplateView):
template_name = 'about_me.html'
class Contact(generic.TemplateView):
template_name = 'contact.html'
class Impressum(generic.TemplateView):
template_name = 'impressum.html'
class StaticContent(generic.TemplateView):
template_name = 'static_html_content.html'
class SideBar(generic.TemplateView):
template_name = 'sidebar.html'
#class PostDetail(generic.DetailView):
# model = Post
# context_object_name = "post"
# template_name = "post_detail.hhml"
def post_detail(request, post):
template_name = 'post_detail.html'
post = get_object_or_404(Post, slug=post, status=1)
comments = post.comments.filter(active=True)
new_comment = None
#comment posted
if request.method == 'POST':
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
# Create comment object but dont save to database yet
new_comment = comment_form.save(commit=False)
# Assign thecurrent post to the comment
new_comment.post = post
#save the comment to the database
new_comment.save()
#redirect to the same page and focus on that comment
return HttpResponseRedirect('/' + post.slug)
#return redirect(post.get_absolute_url()+'#'+str(new_comment.id))
else:
comment_form = CommentForm()
return render(request, template_name, {'post': post, 'comments': comments, 'new_comment': new_comment, 'comment_form': comment_form})
def reply_page(request):
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
post_id = request.POST.get('post_id')
parent_id = request.POST.get('parent')
post_url = request.POST.get('post_url')
print(post_id)
print(parent_id)
print(post_url)
print('was here reply!')
reply = form.save(commit=False)
reply.post = Post(id=post_id)
reply.parent = Comment(id=parent_id)
reply.save()
return redirect(post_url+'#'+str(reply.id))
return redirect('/')
forms.py:
from .models import Comment
from django import forms
from mptt.forms import TreeNodeChoiceField
class CommentForm(forms.ModelForm):
parent = TreeNodeChoiceField(queryset=Comment.objects.all())
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['parent'].widget.attrs.update(
{'class': 'd-none'})
self.fields['parent'].label = ''
self.fields['parent'].required = False
class Meta():
model = Comment
fields = ('name', 'parent', 'email', 'body')
widgets = {
'name': forms.TextInput(attrs={'class': 'col-sm-12'}),
'email': forms.TextInput(attrs={'class': 'col-sm-12'}),
'body': forms.Textarea(attrs={'class': 'form-control'}),
}
def save(self, *args, **kwargs):
Comment.objects.rebuild()
return super(CommentForm, self).save(*args, **kwargs)
post_details.html:
{% extends 'base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% load mptt_tags%}
{% block content %}
<header class="masthead" style="height: 13.9em;">
<!-- javascript add -->
<script src="{% static 'js/main.js'%}"></script>
</header>
<div class="container">
<div class="row">
<div class="col-md-8 card mb-4 mt-3 left top">
<div class="card-body">
<h1>{% block title %} {{ post.title }} {% endblock title %}</h1>
<p class=" text-muted">{{ post.author }} | {{ post.created_on }}</p>
<p class="card-text ">{{ post.content | safe }}</p><br>
<a href="{% url 'home' %}" style="float: right;"
class="btn btn-danger">Go Back</a><br><br>
</div>
</div>
{% block sidebar %} {% include 'sidebar.html' %} {% endblock sidebar %}
</div>
<div class="row">
<div class="col-md-8 card mb-4 mt-3 left top">
<div class="card-body">
<h3>Add Comment</h3>
<form method="POST" action="">
{% csrf_token %}
{{ comment_form | crispy }}
<button type="submit" class="btn btn-danger">Comment</button>
</form>
<!-- count comments section-->
{% with comments.count as total_comments %}
<h3 class="mt-5">
{{ total_comments }} comment{{ total_comments|pluralize }}
</h3>
{% endwith %}
<!-- show comment section -->
<div>
<ul style="list-style-type: none;">
{% recursetree comments %}
<li>
<!-- parent body -->
<div>
<div class="border p-4 rounded">
<h4>{{ node.name }}</h4>
<small class="text-muted">On {{ node.created_on }}</small>
<h5>{{ node.body }}</h5> <br>
<button class="btn btn-danger btn-sm" onclick="handleReply({{node.id}})">Reply</button>
<div id="reply-form-container-{{node.id}}" style="display:none">
<form method="POST" action="{% url 'reply' %}" class="mt-3">
{% csrf_token %}
<input type="hidden" name="post_id" value="{{post.id}}">
<input type="hidden" name="parent" value="{{comment.id}}">
<input type="hidden" name="post_url" value="{{post.get_absolute_url}}">
{{comment_form|crispy}}
<div>
<button type="button" onclick="handleCancel({{node.id}})" class="btn btn-danger border btn-sm">Cancel</button>
<button type="submit" class="btn btn-danger btn-sm">Submit</button>
</div>
</form>
</div>
</div>
</div>
<br>
<!-- if children -->
{% if not node.is_leaf_node %}
<ul ul style="list-style-type: none;">
<div class="children pl-2 pl-md-5">
{{ children }}
</div>
</ul>
{% endif %}
</li>
{% endrecursetree%}
</ul>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}
I've tried to change the values in the formfields of the post_details.html to node.parent.id
but nothing seems to happen.
Also i tried to change the parent_id's datatype to see if there something happens.
but because it runs in this Opperant-Error i think it could be an issue with saving to the mySQL Database...
Ok... Now i have have found the answer.
In views.py i've edited these lines:
parent_id = request.POST.get('parent')
and replace 'parent' with 'commend_id'
parent_id = request.POST.get('comment_id')
In post_detail.html i have changed the form:
<input type="hidden" name="parent" value="{{comment.id}}">
to...
<input type="hidden" name="comment_id" value="{{node.id}}">
Now it runs as expected! YAY!
Firstly I am a beginner at Django but am slowly learning, I have deployed a couple of Django projects, but I have come up against a problem where I have run out of ideas on how to solve due to a lack of knowledge. I have no experience really with the frontend, I have yet to touch Boostrap (although obviously know some HTML ) or JS in detail.
I am using a HTML template to build a Photography portfolio, I have a Album view with image thumbnails which work nicely and I have a href to the list of images within that Album.
The problem is that template uses Boostrap Modal to open the list of images within the same page, this looks very nice and I want to try and keep it working but unsure how to pass my Django data (ie., the slug from the href ) through the modal.
What I have attempted is to split my gallery-detail template which takes in the listview of the Album images filter by that album, and then include that within my main Gallery template which uses my Gallery ListView to show the thumbnails. I though the modal would work this way as they would maybe technically be on the same page?
I'm just unsure, how do I pass view context into modals? Below is my relevant code which hopefully makes it easier to understand what I am trying to do
Where I am at the moment....the modal loads on same page, but no images are shown just the close X icon. If I right-click and open the URL all images open corresponding to that Album correctly but with no css or styling.
Models
name = models.CharField(max_length=200, null=True)
slug = AutoSlugField(populate_from='name')
created = models.DateTimeField()
visable = models.BooleanField(default=False)
type = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True)
image = models.ForeignKey('Media', on_delete=models.CASCADE)
album_images = models.ManyToManyField('Media', related_name="album_pictures")
def __str__(self):
return str(self.name)
class Media(models.Model):
timestamp = models.DateTimeField()
image = models.ImageField(upload_to="media")
order = models.IntegerField(default=0)
visable = models.BooleanField(default=True)
categories = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True)
class Meta:
verbose_name_plural = "Media"
Views. Straightforward enough.
class GalleryView(ListView):
template_name = "main/gallery.html"
model = Albums
class GalleryDetailView(ListView):
template_name = "main/gallery-detail.html"
model = Media
def get_queryset(self):
gallery = get_object_or_404(Albums, slug=self.kwargs['slug'])
print(gallery)
return Media.objects.filter(album_pictures=gallery)
Templates. Gallery.
{% extends "main/base.html" %}
{% load static %}
{% block gallery %}
{% for gallery in object_list %}
<div class="item col-xs-6 col-sm-6 col-md-4">
<figure class="overlay"> <a href="{% url 'main:gallery_detail' gallery.slug %}" data-toggle="modal" data-target="#myModal1">
<div class="text-overlay caption">
<div class="info">
<h2 class="post-title">{{ gallery.name }}</h2>
<div class="meta"> <span class="count">7 Photos</span> <span class="category">Hobby</span></div>
</div>
</div>
<img src="{{ gallery.image.image.url }}" alt="" /></a> </figure>
</div>
{% endfor %}
{% include "main/gallery-detail.html" %}
{% endblock %}
gallery-detail template
{% extends "main/base.html" %}
{% load static %}
{% block gallery %}
{% for gallery in object_list %}
<div class="item col-xs-6 col-sm-6 col-md-4">
<figure class="overlay"> <a href="{% url 'main:gallery_detail' gallery.slug %}" data-toggle="modal" data-target="#myModal1">
<div class="text-overlay caption">
<div class="info">
<h2 class="post-title">{{ gallery.name }}</h2>
<div class="meta"> <span class="count">7 Photos</span> <span class="category">Hobby</span></div>
</div>
</div>
<img src="{{ gallery.image.image.url }}" alt="" /></a> </figure>
</div>
{% endfor %}
{% include "main/gallery-detail.html" %}
{% endblock %}
For the past few days I have been trying to give access to the admin user to upload multiple images/slides for every single post, one idea I had in mind was nesting a for loop inside the posts for loop that for every post, render also every image associated with it but it seem's I cant get it quite right.
class Post(models.Model):
title = models.CharField(max_length = 128)
image = models.ImageField(default = 'default.jpg', upload_to = 'post_pics')
content = models.TextField()
date_posted = models.DateTimeField(default = timezone.now)
category = models.ForeignKey(Category, on_delete = models.CASCADE)
def __str__(self):
return f"{self.title} - {self.category}"
def get_image_filename(instance, filename):
title = instance.post.title
slug = slugify(title)
return "post_images/%s-%s" % (slug, filename)
class Images(models.Model):
post = models.ForeignKey(Post, default= None, on_delete = models.CASCADE, related_name= 'Images')
image = models.ImageField( upload_to = get_image_filename, verbose_name = 'Images')
def __str__(self):
return f"imazh per {self.post}"
and my Html:
<div class="post-list-container">
{% for post in posts %}
<article class="post-container">
<div class="post-top">
> Focus on the for loop here
{% for post.Images in post.Images %}
<img src="{{ post.Images.url }}">
{% endfor %}
<div class="post-title"><h1>{{ post.title }} </h1></div>
<div class="post-images">
<img class="rounded" src="{{ post.image.url }}">
</div>
</div>
<div class="post-middle">
<div class="post-content"><p> {{ post.content }}</p> </div>
</div>
<div class="post-bottom">
<div class="post-category"><h2>{{ post.category }}</h2>
</div>
<div class="post-date_posted"><h1>{{ post.date_posted|date:"F d, Y" }}</h1>
</div>
</div>
</article>
{% endfor %}
</div>
Is there any way to render those images this way?
A Post will have a related set, which is what you refer to that reverse relationship as.
By default, django will make the relationship on a Post instance images_set because it takes your model name on the relationship & adds _set.
You can also choose your own related name by setting the related_name attribute on the FK field. (docs)
Here's an example;
class Map(models.Model):
members = models.ManyToManyField(
User,
related_name='maps',
verbose_name=_('members')
)
# Reverse relationship:
User.maps.all()
Or in python using your models;
post = Post.objects.first()
print(f"Images in post {post.title}")
for image in post.images_set.all():
print(image.url)
So without a custom related_name, your template loop would be something like;
{% for image in post.images_set.all %}
<img src="{{ image.url }}">
{% empty %}
<p>No images found</p>
{% endfor %}
I have a form that isn't rendering and I can't figure out why. The only thing showing is submit button. I created the form having followed the methodology described here, here and here.
I looked at solutions for the problem (listed below amongst others) but they havent helped.
django-forms not rendering errors
django form not rendering in template. Input fields doesn't shows up
Django Form not rendering
Django Form not rendering - following documentation
The html is app_core/index.html which extends another- landing_page/base.html
The html:
{% extends 'landing_page/base.html' %}
{% load i18n %}
{% load staticfiles %}
{% load static %}
{% load bootstrap %}
{%block content %}
<div id="contactus" class="container-fluid">
<br>
<div class="container text-center">
<div class="row">
<div class="col-xs-12 col-sm-10 col-sm-offset-1 col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2 text-left">
<center><h3>{% trans 'Contact Us' %}</h3>
<p>{% trans 'We are at your disposal 365 days 24 hours a day. When you think of languages think of Milingual.
Languages are not studied, they are lived!' %}</p></center>
</div>
</div>
<div class ="row">
<div class="col-xs-12 col-sm-10 col-sm-offset-1 col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2 text-left">
<center><h1>Contact Us</h1><center>
<form id="contactus-form" action="{% url 'contact' %}"method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<br/>
<div class="form-actions">
<button type="submit" class="btn btn-primary pull-center">Send</button>
</div>
</form>
<div>
</div>
</div>
{%endblock content %}
The Views.py
from django.core.mail import BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from .forms import ContactForm
#ContactUs
def contact(request):
if request.method == 'GET':
form = ContactForm()
else:
form = ContactForm(request.POST)
if form.is_valid():
whoareyou = form.cleaned_data['whoareyou']
name = form.cleaned_data['name']
phone_number = form.cleaned_data['phone_number']
subject = form.cleaned_data['subject']
from_email = form.cleaned_data['from_email']
message = form.cleaned_data['message']
try:
send_email(subject, message, whoareyou, from_email, ['thiswaysouth#gmail.com'])
except BadHeaderError:
return HttpResponse('Invalid header found.')
return redirect('success')
return render(request, "/index.html", {'form': form})
def success(request):
return HttpResponse('Success! Thank you for your message.')
The form.py
from django import forms
class ContactForm(forms.Form):
WHOAREYOU_CHOICES = (
('Teacher', 'Teacher'),
('Student', 'Student'),
('Venue', 'Venue'),
('Business', 'Business'),
('Other', 'Other')
)
whoareyou = forms.ChoiceField(choices=WHOAREYOU_CHOICES, required=True)
name = forms.CharField(required=True)
phone_number = forms.CharField(required=True)
from_email = forms.EmailField(required=True)
subject = forms.CharField(required=True)
message = forms.CharField(widget=forms.Textarea, required=True)
And the urls.py
from django.conf.urls import url, include
from .views import *
from app_core import views
urlpatterns = [
url(r'^$', IndexPage, name='index'),
# setting session city
url(r'^get-city-session$', GetCitySession, name='get-city-session'),
url(r'^set-city-session$', SetCitySession, name='set-city-session'),
url(r'^contact/$', views.contact, name='contact'),
url(r'^success/$', views.success, name='success'),
]
You need to put your code inside blocks otherwise it doesn't know where to put it when you extend. In your base.html, you can do something like
{% block body %}
{% endblock %}
And then in your index.html page, you need to surround everything that you want to appear in that spot in your base.
{% block body %}
... Code goes here ...
{% endblock %}
This ended having a very simple solution that I failed to notice simply because of my naivete and newness to programming. The above code was and is perfectly correctly but I neglected to add crucial line of code in the ContactForm code in form.py. At the end of the form I was simply to add the following lines and it rendered perfectly:
class ContactForm(forms.Form):
WHOAREYOU_CHOICES ...
class Meta:
fields =('whoareyou','name','phone_number','from_email','subject','message')
I have a problem using the for loop tag, It is fine for tabs but the reference for id in tab content itself is the problem as I can't access the instant value of in {{spec}} and now How can I customize my url with nav pills tabs to show the courses related to specializations,
category_page.html
<!-- This is tabs with for loop for data in specializations worked well-->
<div class="row" >
<div class="list-group col-md-4" role="navigation">
{% for specs in spec %}
<button type="button" class="list-group-item" data-toggle="tab" href="{{ specs }}">{{ specs }}</button>
{% endfor %}
</div>
<!-- Here is the tab content and it doesn't work well as I need data appears related to the tab itself -->
<div class="col-md-8">
<div class="tab-content ">
{% for specs in spec %}
<div id="{{ specs }}" class="tab-pane fade ">
<div class="row">
{% for instances in courses_spec %}
<div class="col-sm-6 col-md-6">
<div class="caption">
<h3>{{ instances.name }}</h3>
</div>
</div>
{% endfor %}
</div>
</div>
views.py
def categories_pages(request, category_name, speci_name=None):
courses = Course_dir.objects.filter(
availability=True,
id_CO__id_S__name=category_name
).order_by('date')
courses_spec = Course_dir.objects.filter(
availability=True,
id_CO__name=speci_name
).order_by('date')
spec = Specialization.objects.filter(
id_S__name__contains=category_name
).order_by('name')
context = {
"courses": courses,
"spec": spec,
"courses_spec": courses_spec
}
return render(request, 'categories/categories-page.html', context)
urls.py
url(r'^categories/(?P<category_name>[-\w]+)/$', views.categories_pages, name='category_detail'),
url(r'^categories/(?P<category_name>[-\w]+)/(?P<speci_name>[-\w]+)$', views.categories_pages, name='specialization_detail'),
models.py
class Category(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=300, blank=True)
slug = models.SlugField(default=None)
def get_absolute_url(self):
self.slug = slugify(self.name)
return reverse('category_detail', args=[str(self.slug)])
class Specialization(models.Model):
id_S = models.ForeignKey(Category, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
slug = models.SlugField(default=None)
def __str__(self):
return self.name
def get_absolute_url(self):
self.slug = slugify(self.name)
return reverse('spec_detail', args=[str(self.slug)])
A couple things -
You aren't calling get_absolute_url anywhere, so the template will only display the return value of the model's __unicode__ method (if Python 2) or __str__ method (if Python 3).
Don't call for spec in spec, use separate variables so there isn't namespace pollution and potential errors.
{% for each_spec in spec %}
<button type="button" class="list-group-item" data-toggle="tab"
href="{{ each_spec.get_absolute_url }}">{{ spec }}</button>
{% endfor %}