ImproperlyConfigured at /app/category/Python/ - 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.

Related

How can I get my html to display my django model?

I'm trying to get my django model to be shown in the footer of my base.html but I can't get it to show up. I've looked at a few videos and I can't figure out where I'm going wrong. I know that the model works as I've made 4 entries in my database and I can view them on the admin page. The code also doesn't show any errors so I have nothing to go off of there. Here it is:
Models.py
class SocialMediaPlatform(models.Model):
name = models.CharField(max_length=50, blank=True, null=True)
font_awesome_class = models.CharField(max_length=50, blank=True, null=True)
base_url = models.CharField(max_length=50, blank=True, null=True,
default='https://instagram.com/ or https://tiktok.com/#')
def __str__(self):
return self.base_url
Views.py
def social_media_base_view(request):
context = {}
smbase = SocialMediaPlatform.objects.all()
context['smbase'] = smbase
return render(request, 'base.html', context)
Urls.py
urlpatterns = [
path('', views.social_media_base_view),
]
Admin.py
#admin.register(SocialMediaPlatform)
class SocialPlatformAdmin(admin.ModelAdmin):
list_display = ('name', 'font_awesome_class', 'base_url')
base.html
{% for smlink in smbase %}
<a href="{{ smlink.name }}">
<i class="{{ smlink.font_awesome_class }}">
</a>
{% endfor %}
Look what you are passing as context:
def social_media_base_view(request):
...
smbase = SocialMediaPlatform.objects.all()
context['smbase'] = smbase
return ...
It's QuerySet of SocialMediaPlatform objects. It means, that you can render them one by one with for loop:
{% for smlink in smbase %}
{{ smlink.name }}
{% endfor %}
You don't need to call SocialMediaPlatform model additionaly.
in your view you use:
return render(request, 'index.html', context)
i can not see, if you are defined index.html
Somethere in index you should have
{% extends base.htm %}
The second, i am agree with #Shabble:
{% for smlink in smbase %}
<a href="{{ smlink.name }}">
<i class="{{ smlink.font_awesome_class }}">
</a>
{% endfor %}
The last:
Try to use Django-GCBV TemplateView. Or ListView, in your case it is better:
somethere in views.py
Class MyListView(ListView):
model = SocialMediaPlatform
template_name = index.html
somethere in urls.py
urlpatterns = [
path('', MyListView.as_view()),
]
somethere in index.html
{% for smlink in object_list %}
<a href="{{ smlink.name }}">
<i class="{{ smlink.font_awesome_class }}">
</a>
{% endfor %}

Redirected to same page after POST method django

I am creating this project in django. I am working on reporting films, where I go to a film-detail view, then hit the report button. A report_form shows up where I justify why I am reporting, and then I click report. Everything works fine, but there is one thing. After reporting I get sent back to a random(?) film-detail view, but I would like to go back to the view for the film I am reporting. But how???
views.py
class FilmReportView(LoginRequiredMixin, CreateView):
model = Report
fields = ['reason']
def form_valid(self, form):
form.instance.reporter = self.request.user
form.instance.reports_id = self.kwargs['pk']
return super().form_valid(form)
def get_success_url(self):
return "film/<int:pk>/report"
report_form.html
{% extends "board/base.html" %}
{% load crispy_forms_tags %}
{% load materializecss %}
{% block content %}
<div class="valign-wrapper row login-box">
<div class="col card hoverable s10 pull-s1 m6 pull-m3 l8 pull-l2">
<form method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
<div class="card-content">
<span class="card-title">Jusity why you want to report this film?</span>
<div class="row">
{{ form|materializecss }}
</div>
</div>
<div class="card-action right-align">
<input type="reset" id="reset" class="btn-flat grey-text waves-effect">
<input type="submit" class="btn green waves-effect waves-light" value="Report">
</div>
</form>
</div>
</div>
{% endblock content %}
urls.py
urlpatterns = [
path("", views.films_view, name="board-home"),
path("film/add", FilmAddView.as_view(), name="film-add"),
path("film/<int:pk>/", FilmDetailView.as_view(), name="film-detail"),
path("film/<int:pk>/report", FilmReportView.as_view(), name="film-report"),
]
models.py
class Report(models.Model):
reason = models.TextField()
reporter = models.ForeignKey(User, on_delete=models.CASCADE, related_name="Reporter")
reports = models.ForeignKey(Film, on_delete=models.CASCADE)
def __str__(self): # pragma: no cover
return f"{self.reports.title} reported by {self.reporter.username}"
def get_absolute_url(self): # pragma: no cover
return reverse("film-detail", kwargs={"pk": self.pk})
Fix your FilmReportView get_success_url() to look like that:
def get_success_url(self):
return reverse("film-detail", kwargs={"pk": self.object.reports.id})
That should take care of it
In your views.py or even in the template you can put next parameter with url you want:
form/action/url?next={{request.path}}
See more about next:
https://www.reddit.com/r/django/comments/32s9ag/how_do_i_set_the_next_context_variable_in_django/

Django: Problem with Adding Clickable Link in the Second Template

I am a beginner in Django. I am building a Django app, named PhoneReview. It will store reviews related to the latest mobile phone. It will also display phone brands, along with the associated phone models.
I have already created models and views. I have also managed to add clickable link in the first template (brandlist.html). In the first template, when you click on the brand name, like Samsung, you will be taken to the page of the phone model, like Galaxy S10.
Here is the screenshot of the first template:
When you click the link, you will be taken to the second template (phonemodel.html). But now, I am facing an issue. There is no clickable link on the phone model ("Galaxy S10") that will direct you to details.html. Here is the screenshot.
Here are the codes of models.py inside the "PhoneReview" folder:
from django.db import models
from django.template.defaultfilters import slugify
# Create your models here.
class Brand(models.Model):
brand_name = models.CharField(max_length=100)
origin = models.CharField(max_length=100)
manufacturing_since = models.CharField(max_length=100, null=True, blank=True)
def __str__(self):
return self.brand_name
def save(self, *args, **kwargs):
self.slug = slugify(self.brand_name)
super().save(*args, **kwargs)
class PhoneModel(models.Model):
brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
model_name = models.CharField(max_length=100)
launch_date = models.CharField(max_length=100)
platform = models.CharField(max_length=100)
def __str__(self):
return self.model_name
class Review(models.Model):
phone_model = models.ManyToManyField(PhoneModel, related_name='reviews')
review_article = models.TextField()
date_published = models.DateField(auto_now=True)
slug = models.SlugField(max_length=150, null=True, blank=True)
def __str__(self):
return self.review_article
Here are the codes of urls.py inside the "PhoneReview" folder:
from . import views
from django.urls import path
urlpatterns = [
path('index', views.BrandListView.as_view(), name='brandlist'),
path('phonemodel/<int:pk>/', views.ModelView.as_view(), name='modellist'),
path('details/<int:pk>/', views.ReviewView.as_view(), name='details'),
]
Here are the codes of views.py inside the "PhoneReview" folder:
from django.views import generic
from .models import Brand, PhoneModel, Review
class BrandListView(generic.ListView):
template_name = 'PhoneReview/brandlist.html'
context_object_name = 'all_brands'
def get_queryset(self):
return Brand.objects.all()
class ModelView(generic.DetailView):
model = PhoneModel
template_name = 'PhoneReview/phonemodel.html'
class ReviewView(generic.DetailView):
model = Review
template_name = 'PhoneReview/details.html'
Here are the codes of apps.py inside the "PhoneReview" folder:
from django.apps import AppConfig
class PhonereviewConfig(AppConfig):
name = 'PhoneReview'
Here are the codes of details.html inside the "templates" folder:
{% extends 'PhoneReview/base.html' %}
{% load static %}
<html>
<link rel="stylesheet" type="text/css" href="{% static "css/style.css" %}">
<html lang="en">
{% block title%}Details{% endblock %}
{% block content %}
<h1>This is the Details Page</h1>
<h2>Review:</h2>
<p>{{ review.review_article }}</p>
<h2>News Link:</h2>
<p>{{ review.slug }}</p>
{% endblock %}
</html>
Here are the codes of phonemodel.html inside the "templates" folder:
{% extends 'PhoneReview/base.html' %}
{% load static %}
{% block title%}
Phone Model Page
{% endblock %}
{% block content %}
<!--Page content-->
<h1>This is Phone Model Page</h1>
<h2>Here is the phone model</h2>
<ul>
<li>{{ phonemodel.model_name }}</li>
</ul>
<img src="{% static "images/brandlist.jpg" %}" alt="Super Mario Odyssey" /> <!-- New line -->
{% endblock %}
I tried replacing <li>{{ phonemodel.model_name }}</li> with <li>{{ phonemodel.model_name }}</li>. But I get an error, which looks like this:
NoReverseMatch at /phonemodel/1/
Reverse for 'details' with arguments '('',)' not found. 1 pattern(s) tried: ['details/(?P<pk>[0-9]+)/$']
How can I fix the issue?
There is no context variable named brand and you don't need it anyway. You should use the id of the phonemodel:
<li>
<a href = "{% url 'details' phonemodel.id %}">
{{ phonemodel.model_name }}
</a>
</li>

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 %}

Django, my for loop is not showing in include template

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.

Categories