Django, my for loop is not showing in include template - python

Hello I am a beginner with Django and Python. I am currently in my project using a for loop in the template but it does not show anything. Could someone help me and explain me what I am doing wrong?
models.py
class ImageCategory(models.Model):
name = models.CharField(blank=False, max_length=120)
created_at = models.DateTimeField(default=datetime.now(), blank=True)
class Meta:
verbose_name_plural = "image categories"
def __str__(self):
return self.name
views.py
from .models import ImageCategory
def HomeView(request):
template = loader.get_template('editor.html')
return HttpResponse(template.render())
def LibraryOverviewView(request):
return render(request, 'library_overview.html', {'image_categories': ImageCategory.objects.all()})
So I put the category information in the libraryOverView, but the editor.html is using HomeView. library_overview.html is included in another html called editor.html
editor.html
section class="toolbox document-tools">
<ul>
<li class="tb-title">Document</li>
<!-- uncomment to see all available styles -->
<!--
<li class="tb-btn tb-btn-big tb-btn-disabled">Preview</li>
-->
<li class="tb-btn tb-btn-big" id="btn-export">Export</li>
<li class="tb-btn tb-btn-big tb-btn-action">Save</li>
</ul>
</section>
</span>
{% include 'library_overview.html' %}
{% include 'library_categories/colorful_images.html' %}
{% include 'library_categories/colorful_images_categories/blue_images.html' %}
</span>
library_overview.html
{% for category in image_categories %}
<a class="tb-btn tb-btn-label tb-btn-radio no-bg slide-forward">-> {{ category.name }}</a>
{% empty %}
<p> There are no Categories yet </p>
{% endfor %}
urls.py
urlpatterns = [url(r'^library_overview/', views.LibraryOverviewView,
name='LibraryOverviewView'),

The editor.html is using the HomeView, and not LibraryOverviewView. But the html for libraryOverviewView was included inside editor.html, thus still using the HomeView. Moving the information from LibraryOverView to HomeView worked.

Related

Django: export csv file with django_table2

I want to have an download button a html page that renders a django table.
I followed the documentation of django2 and this post How to export .csv with Django-Tables2? was helpful but could not make the trick.
I feel like I have done everything correctly (according to my beginner skills), there is no error but the download button is not there.
I was wondering if someone has any help to provide on this one
table.py
class AnormalTable(tables.Table):
class Meta:
model = stock_anormal
template_name = "django_tables2/bootstrap4.html"
export_formats = ['csv', 'xlsx']
view.py
#method_decorator(login_required, name='dispatch')
class PostDetailalerte_negat(LoginRequiredMixin,APIView, tables.SingleTableMixin, ExportMixin):
def get(self, request):
queryset = stock_negatif.objects.all()
table = NegatTable(queryset)
RequestConfig(request).configure(table)
export_format = request.GET.get("_export", None)
if TableExport.is_valid_format(export_format):
exporter = TableExport(export_format, table)
return exporter.response("table.{}".format(export_format))
return render(request, 'detailstocknegat.html', {'table':table})
html snipet
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">ITEMS IN ALERTE SAFETY STOCK LEVEL</h1>
<div>
{% for format in view.export_formart %}
<i class="fas fa-download fa-sm text-white-50"></i> Generate Report
{% endfor %}
</div>
</div>
<table>
{% load django_tables2 %}
{% render_table table %}
</table>
I'm not sure if this will fix this specific problem but I ran into basically the same issue and this is how I solved it:
I moved the export_formats = ['csv', 'xlsx'] that was in table.py originally into the view for my table (view.py in this example). Then I passed export_formats directly to the html by changing the return code in views.py : return render(request, 'detailstocknegat.html', {'table':table, 'export_formats':export_formats}).
Then in the html for my table (html snipet in this example) I changed the for statement to be:
{%for format in export_formats %}>
<a href="{% export_url format %}">
download <code>.{{ format }}</code>
</a>
{% endfor %}
I hope this helps somebody out there!

How to render links in a template for database filtering in django

I am using the "keyone" column in the database to filter entries. So far in the code i have written i am successfully able to render template with "keyone = 2" values. what should i write in a new template file, and how should i modify existing views.py so that when the template file renders it contains a list of links , each link for each value of "keyone" , when i click on the link say "keyone = 2", the selected entries should get rendered in home.html
models.py
# app/models.py
from django.db import models
from django.urls import reverse # new
class Post(models.Model):
text = models.TextField()
def __str__(self):
return self.text[:50]
keyone = models.IntegerField(default = '777')
def get_absolute_url(self): # new
return reverse('post_detail', args=[str(self.id)])
views.py
def HomePageView(request):
key2select = Post.objects.filter(keyone=2)
return render(request, 'home.html', {
'key2select': key2select,
})
home.html
<ul>
{% for post in key2select %}
<li>{{ post.keyone }}&nbsp &nbsp{{ post.text }}</li>
{% endfor %}
</ul>
sample database
desired rendering
Firstly, we need to get all keyone values in the DB, to be passed to home.html.
Then in home.html, we need a navbar or somewhere else to put all these links which represent all the keyone values.
So the code would be like:
models.py
# app.models.py would remain the same
views.py
def homePageView(request, key):
key2select = Post.objects.filter(keyone=key)
keyones = Post.objects.distinct('keyone')
return render(request, 'home.html', {
'key2select': key2select,
'keyones': keyones
})
You can check the distinct() in the Django Docs to get distinct values of a column in DB
home.html
<!-- home.html -->
<nav>
<ul>
{% for key in keyones %}
<li>somthing {{key}} something</li>
{% endfor %}
</ul>
</nav>
...
<ul>
{% for post in key2select %}
<li>{{ post.keyone }}&nbsp &nbsp{{ post.text }}</li>
{% endfor %}
</ul>
As we passed the key to the url in the nav link, we need to change the url pattern to catch this.
urls.py
urlpatterns =[
...
path('home/<int:key>/', views.homePageView, name='home')
...
]
May be I'm not understand you problem, if you'r looking for create a list of link code should be
<ul>
{% for post in key2select %}
<a href="{% url "post_detail" post.id %}"><li>{{ post.keyone }}&nbsp &nbsp{{ post.text }}</li><a/>
{% endfor %}
</ul>
This will contain every post link with list item
thanks #sheng-zhuang for providing the solution. Here is the working code with some slight modifications for my benefit.
I created a new template select.html and here is the logic -
Views.py
class IndexView(TemplateView):
template_name = 'index.html'
def SelectView(request):
keyones = Post.objects.values_list('keyone',flat=True).distinct()
return render(request, 'select.html', {
'keyones': keyones
})
def HomePageView(request, key):
key2select = Post.objects.filter(keyone=key)
return render(request, 'home.html', {
'key2select': key2select,
})
index.html
<header>
Select<br />
Post
</header>
select.html
<nav>
<ul>
{% for key in keyones %}
<li>Keyone value = {{key}} </li>
{% endfor %}
</ul>
</nav>
home.html
<header>
Select<br />
Post
</header>
<br /><br /><br /><br />
<ul>
{% for post in key2select %}
<li>{{ post.keyone }}&nbsp &nbsp{{ post.text }}</li>
{% endfor %}
</ul>
urls.py
path('', IndexView.as_view(), name='index'),
path('select/', SelectView, name='select'),
path('home/<int:key>/', HomePageView, name='home')

How to display post and related comments on single page?

I am unable to design a code to render one particular post and it's related comments. The issue is maybe in views.py or the url.
I have looked at multiple sources without any results. I am a novice to coding and feel like I am missing some essential point. Posts and comments are getting created correctly and all comments get the correct post_id assigned.
My models.py is set up like this:
class Post(models.Model):
title = models.CharField(max_length=1000)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog-home')
class Comment(models.Model):
cid = models.AutoField(primary_key=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
comment = models.TextField()
comment_date = models.DateTimeField(default=timezone.now)
def save(self, *args, **kwargs):
super(Comment, self).save(*args, **kwargs)
def __str__(self):
return self.comment
def get_absolute_url(self):
return reverse('blog-home')
My views.py is set up like this:
class PostDetailView(DetailView):
model = Post
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['comment_list'] = Comment.objects.filter(post=WHAT SHOULD GO HERE?)
return context
I need to pass the Post.id or primary key of the post in the filter above. Can someone explain what it should be?
The url used to access the post detail is as follows:
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail')
I get the post detail view rendered out as the author, title and content of the post when I have the following in views.py:
class PostDetailView(DetailView):
model = Post
The template for that is as below:
{% extends "blog/base.html" %}
{% block content%}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{object.author.profile.image.url}}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'user-posts' object.author.username %}">{{ object.author }}</a>
<small class="text-muted">{{ object.date_posted|date:"F d, Y P e" }}</small>
{% if object.author == user %}
<div><a class="btn btn-secondary btn-sm m-1 mb-1" href="{% url 'post-update' object.id%}">Update</a>
<a class="btn btn-danger btn-sm m-1 mb-1" href="{% url 'post-delete' object.id%}">Delete</a></div>
{% endif %}
</div>
<h2 class="article-title">{{ object.title }}</h2>
<p class="article-content">{{ object.content }}</p>
</div>
</article>
{% for comment in comment_list %}
<div class='article-content'>
<p>{{comment}}</p>
</div>
{% endfor %}
{% endblock %}
How should I take the post.id or pk of the Post and use it to filter the comments related only to that particular post?
Also, what is a good way to set up a template for rendering the queryset?
You should be able to iterate over the reverse link from Post object to the Comment objects linked to it (by default as comment_set) in your template:
{% for comment in post.comment_set %}
If you want greater control you inject a queryset into the context, something like this, to get the most recent six comments only.
"comments": post.comment_set.order_by("-comment_date")[:6]
The post object selected should be available as self.object in a DetailView and will be default be injected into the render context as object. An invaluable resource for navigating the structure of Django Class-based views is the Classy CBV
site.
Warning: this is "off the top of my head" so don't assume it's all perfect.
A single object will have access to its related objects.
Try this:
class PostDetailView(DetailView):
model = Post
# There's no need to define get_context_data() here
Now your template will have the post available as post (and also object).
All of the comments that have this post are available on the template like this:
{% for comment in post.comment_set.all %}
<div class='article-content'>
<p>{{ comment }}</p>
</div>
{% endfor %}

ImproperlyConfigured at /app/category/Python/

I wanna make a page which shows POST's models' contents is shown each category.For example, when I put Python link in in detail.html,only POST's models' contents with Python's category is shown in category.html.When I put Python link in category.html,I got an error,ImproperlyConfigured at /app/category/Python/ CategoryView is missing a QuerySet. Define CategoryView.model, CategoryView.queryset, or override CategoryView.get_queryset(). I wrote codes in views.py
def top(request):
content = POST.objects.order_by('-created_at')[:5]
category_content = Category.objects.order_by('-created_at')[:5]
page = _get_page(blog_content, request.GET.get('page'))
return render(request, 'top.html',{'content':content,'category_content':category_content,"page":page})
class CategoryView(BaseListView):
template_name = 'category.html'
def get_queryset(self):
category_name = self.kwargs['category']
self.category = Category.objects.get(name=category_name)
queryset = super().get_queryset().filter(category=self.category)
return queryset
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['category'] = self.category
return context
in urls.py
urlpatterns = [
path('top/', views.top, name='top'),
path('category/<str:category>/',views.CategoryView.as_view(), name='category'),
]
in models.py
class Category(models.Model):
name = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class POST(models.Model):
title = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return self.title
in top.html
<div class="list-group">
<a href="#">
Category
</a>
<div>
{% for category in category_content %}
<a href="{% url 'category' category.name %}">
{{ category.name }}
</a>
{% endfor %}
</div>
</div>
in category.html
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Category</title>
</head>
<body>
<div>
{% for content in queryset %}
<h2>{{ content.title }}</h2>
<img src="content.image.url" />
<a class="btn btn-outline-primary btn-lg btn-block" href="{% url 'detail' content.pk %}">SHOW DETAIL</a>
{% endfor %}
</div>
<div>
<a href="#" class="list-group-item active">
Category
</a>
<div>
{% for category in category_content %}
<a class="list-group-item justify-content-between" href="{% url 'category' category.name %}">
{{ category.name }}
</a>
{% endfor %}
</div>
</div>
</body>
</html>
I really cannot understand why ImproperlyConfigured which means settings.py is wrong.When I changed BaseListView into ListView,same error happens.I wrote get_queryset in CategoryView's class so I cannot understand codes needs QuerySet. How should I fix this?What is wrong in my codes?
One issue is that you're calling super().get_queryset(), which expects your class to define a queryset or a model. Adding model = Category will fix that error.
It looks like you're returning a queryset with just one entry, though. If you only want to get the one category, it would be simpler to use a DetailView:
from django.views.generic import DetailView
from .models import Category # or wherever it is
class CategoryView(DetailView):
model = Category
template_name = 'category.html'
def get_object(self):
category_name = self.kwargs['category']
return Category.objects.get(name=category_name)
Note that your template would need to be updated to reference category or object instead of looping through the queryset.

Django 1.8. Can't show an image in form

I'm using this package https://github.com/tomwalker/django_quiz to make a web quiz app. I need to add images to the multiplechoice answers.
So, I added to the Answers model:
image = models.ImageField(upload_to='uploads/%Y/%m/%d',
blank=True,
null=True,
verbose_name=_("Image"))
Images are uploading and saving into the DB.
The part that shows choosable answers are shown in template like this:
{% for answer in form.answers %}
<li class="list-group-item">
{{ answer }}
</li>
{% endfor %}
I changed it to:
{% for answer in form.answers %}
<li class="list-group-item">
{{ answer }}
<img src="{{ answer.image.url }}" alt="" />
</li>
{% endfor %}
But it's doesn't work. It renders <img src(unknown)>
This is forms.py:
class QuestionForm(forms.Form):
def __init__(self, question, *args, **kwargs):
super(QuestionForm, self).__init__(*args, **kwargs)
choice_list = [x for x in question.get_answers_list()]
self.fields["answers"] = forms.ChoiceField(choices=choice_list,
widget=RadioSelect)
And this is model:
def get_answers_list(self):
return [(answer.id, answer.content) for answer in
self.order_answers(Answer.objects.filter(question=self))]
I know this is old but I recently came across this problem, in case anyone out there is still stuck on it, here is how I solved it:
Create a ImageField in the Answer model
image = models.ImageField(upload_to='images/',
blank=True,
null=True,
verbose_name=_("Image"))
Add a model method on MCQuestion
from django.utils.safestring import mark_safe
...
def get_answers_images(self):
return [(answer.id, mark_safe(f"<img src='{answer.image.url}'/>")) for answer in
self.order_answers(Answer.objects.filter(question=self))]
In forms.py
image_choice_list = [x for x in question.get_answers_images()]
self.fields["answers"] = forms.ChoiceField(choices=image_choice_list,
widget=RadioSelect)
PS: You might also want to change your QuizTake in views.py in other to not conflict with other types of questions, in my case I separated the forms for MCQuestion and TFQuestion
# New
elif self.question.__class__ is TF_Question:
form_class = TF_QuestionForm
I hope this saves someone else from wasting hours on something relatively simple. While injecting the img tag directly might not be the "cleanest" approach I think it works well enough and doesn't require you to mess around much with the existing logic structure of the quiz app.
to display image :-
add {% load static %} in template
sample snippet:-
{% block content %}
{% load static %}
Product List
{% if product %}
{% for prd in product %}
<div class="gallery">
<a target="_blank" href="{% static prd.image1 %}">
<img src="{% static prd.image1 %} " alt="{{ prd.name }}" width="400" height="400">
</a>
<div class="desc"> {{ prd.name }}</div>
</div>
{% endfor %}
{% else %}
<p>There are no products entered by you .</p>
{% endif %}
{% endblock %}
in url.py
from django.conf.urls import url
from django.contrib import admin
**from django.conf import settings**
**from django.conf.urls.static import static**
from . import views
from .views import Productlistview,Productdetailview
app_name= 'product'
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^add/$', views.addproduct, name='addproduct'),
url(r'^addsuccess/$', views.addsuccess, name='addsuccess'),
url(r'^productview/$', Productlistview.as_view(), name='viewproduct'),
url(r'^productview/(?P<productid>[0-9a-f-]+)/view/$',Productdetailview.as_view(), name='productdetailview'),
] **+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)**
in settings.py -- project setings
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
'/dev/projects/pro_mysql_practice/product/',
'dev/projects/pro_mysql_practice/index/',
]

Categories