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 %}
Related
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 }}   {{ 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 }}   {{ 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 }}   {{ 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 }}   {{ 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')
Hello i am struggling already since 2 days to get a reverse relation going.
I am trying to get pictures of "bilder" into related "doku".
The site returns the {{doku.name}} but nothing from the loop from the related model "bilder"
I tried almost everything i have found on the internet, but maybe I just have overseen something?
here is my models.py:
class Doku(models.Model):
name = models.CharField(max_length=1000)
inhalt = models.TextField(blank=True, null=True)
erstellungsdatum = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = "Dokumentation"
verbose_name_plural = "Dokumentationen"
def __str__(self):
return self.name
class Bilder(models.Model):
doku = models.ForeignKey(Doku, on_delete=models.CASCADE)
name = models.CharField(max_length=1000)
bilder = models.ImageField(upload_to="bilder/doku/")
def __str__(self):
return self.name
my views.py
#login_required(login_url='login')
def Dokus(request):
doku = Doku.objects.all()
context = {'doku':doku}
return render(request, "doku/index.html", context)
and my template:
{% for doku in doku %}
{{ doku.name }}
{{ doku.bilder.name }}
{% for bilder in doku.bilder_set.all %}
<img src="{{ bilder.bilder.url }}">
<p>{{ bilder.name }}</p>
{% endfor %}
{% endfor %}
EDIT: here's my urls.py:
from django.urls import path
from . import views
from django.contrib.auth import views as auth_views
app_name = "apps"
urlpatterns = [
path('doku/', views.Dokus, name="Doku"),
path('doku/create', views.DokuCreate.as_view(), name="DokuCreate"),
path('doku/detail/<int:pk>', views.DokuDetail.as_view(), name="DokuDetail"),
path('doku/update/<int:pk>', views.DokuUpdate.as_view(), name="DokuUpdate"),
path('doku/delete/<int:pk>', views.DokuDelete.as_view(), name="DokuDelete"),
path('doku/picadd', views.BilderCreate.as_view(), name="DokuBilderCreate"),
]
{{ doku.bilder.name }} isn't going to work. Remove that.
Similarly, {{dokubilder.dokubilder.url}} isn't going to work because there is no dokubilder in your template context.
For the models you have posted, looping through {% for bilder in doku.bilder_set.all %} in your template should work. If it doesn't, you'll need to provide more information about how to reproduce the problem.
I would suggest that you use different variable names for the instance and the queryset, e.g. {% for doku in docku_list %}. If you change it to docku_list, remember to update your view.
{% for doku in dokus %}
{{ doku.name }}
{% for bilder in doku.bilder_set.all %}
<p>{{ bilder.name }}</p>
{% endfor %}
{% endfor %}
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.
I have a system setup to show comments on a post detail page, however the comments are not showing. I have been focusing on the template tags, because I have used this view code elsewhere and it has worked, however I may be wrong. No errors returning, just not showing the comment in the detail view.
userpost_detail.html:
{% extends 'base.html' %}
{% block content %}
<div class="main">
<h1 class="posttitle">{{ userpost.title }}</h1>
<p class="postcontent">{{ userpost.post_body }}</p>
{% if request.user.is_authenticated and request.user == post.author %}
<a class="link" href="{% url 'feed:edit_post' post.id %}">Edit Post</a>
{% endif %}
Add Comment
{% for comment in userpost.usercomment.all %}
{% if user.is_authenticated %}
{{ comment.create_date }}
<!--
<a class="btn btn-warning" href="{% url 'comment_remove' pk=comment.pk %}">
<span class="glyphicon glyphicon-remove"></span>
</a>
-->
<p>{{ comment.comment_body }}</p>
<p>Posted By: {{ comment.author }}</p>
{% endif %}
{% empty %}
<p>No Comments</p>
{% endfor %}
</div>
{% include 'feed/sidebar.html' %}
{% endblock %}
app PostDetailView:
class PostDetailView(DetailView):
model = UserPost
app add_comment_to_post view:
#login_required
def add_comment_to_post(request,pk):
post = get_object_or_404(UserPost,pk=pk)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.author = request.user
comment.save()
return redirect('feed:post_detail', pk=post.pk)
else:
form = CommentForm()
return render(request,'feed/comment_form.html',{'form':form})
app urls:
from django.conf.urls import url
from feed import views
app_name = 'feed'
urlpatterns = [
url(r'^new/$',views.CreatePostView.as_view(),name='new_post'),
url(r'^post/(?P<pk>\d+)$',views.PostDetailView.as_view(),name='post_detail'),
url(r'^post/(?P<pk>\d+)/edit/$',views.UpdatePostView.as_view(),name='edit_post'),
url(r'^post/(?P<pk>\d+)/delete/$',views.DeletePostView.as_view(),name='delete_post'),
url(r'^post/(?P<pk>\d+)/comment/$',views.add_comment_to_post,name='add_comment'),
]
Models.py:
from django.db import models
from django.core.urlresolvers import reverse
from django.conf import settings
from django.contrib.auth import get_user_model
User = get_user_model()
# Create your models here.
class UserPost(models.Model):
author = models.ForeignKey(User,related_name='userpost',null=True)
post_date = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=150,blank=False)
post_body = models.TextField(max_length=1000,blank=False)
def publish(self):
self.save()
def get_absolute_url(self):
return reverse('index')
def __str__(self):
return self.title
class UserComment(models.Model):
post = models.ForeignKey('feed.UserPost',related_name='comments')
author = models.ForeignKey(User,related_name='usercomment')
comment_date = models.DateTimeField(auto_now_add=True)
comment_body = models.TextField(max_length=500)
def publish(self):
self.save()
def get_absolute_url(self):
return reverse("userpost_list")
def __str__(self):
return self.comment_body
As #user6731765 mentioned you need comments coz of related_name
{% for comment in userpost.comments.all %}
When you get comment_remove error
You need to define a url for comment_remove and define a view for that.
urlpatterns = [
. . . . . .
url(r'^comment/remove/(?P<pk>\d+)/$',views.DeleteCommentView.as_view(),name='comment_remove'),
]
Then in views.py
class DeleteCommentView(DeleteView):
model=UserComment
Due to the related_name you are using for posts in UserComment, try using
{% for comment in userpost.comments.all %}
in your template instead.
I am designing a video rendering kids website.
The app has parent categories for eg: Cartoons, Education shows etc. Each category has multiple posts such as Jungle_book,Duck_tales etc for cartoons.
Each post has multiple episodes.
I am using generic views(listview, Detailview) for views.
Here are my Models.py
from django.db import models
from personal.models import Post
class cartoons_post(models.Model):
category= models.ForeignKey(Post, on_delete=models.CASCADE)
title = models.CharField(max_length = 140)
thumbnail=models.ImageField()
date=models.DateField()
def __unicode__(self):
return self.title
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("posts:detail", kwargs={"id": self.id})
class post_episode(models.Model):
post_id= models.ForeignKey(cartoons_post, on_delete=models.CASCADE)
title = models.CharField(max_length = 140)
thumbnail=models.ImageField()
date=models.DateField()
video=models.FileField()
def __unicode__(self):
return self.title
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("posts:detail", kwargs={"id": self.id})
Here is my urls.py
from django.conf.urls import url, include
from django.views.generic import ListView, DetailView
from cartoons.models import cartoons_post,post_episode
from django.contrib.auth.decorators import login_required
urlpatterns = [
url(r'^$', login_required(ListView.as_view(
queryset=cartoons_post.objects.all().order_by("-date")[:10],
template_name="cartoons/cartoons.html"))),
url(r'^(?P<pk>\d+)$', login_required(ListView.as_view(
queryset=post_episode.objects.filter(post_id=1).order_by("-date"),
template_name="cartoons/post.html"))),
url(r'^(?P<pk>\d+\d+)$',login_required(DetailView.as_view(
model = post_episode,
template_name="cartoons/post_episode.html"))),
]
Here are my three templates
cartoons.html
{% extends "personal/header.html" %}
{% load staticfiles %}
{% block content %}
{% for cartoons_post in object_list %}
<img src= "{{cartoons_post.thumbnail.url}}" width="200" height="220">
{% endfor %}
{% endblock %}
post.html
{% extends "personal/header.html" %}
{% load staticfiles %}
{% block content %}
{% for post_episode in object_list %}
<img src= "{{post_episode.thumbnail.url}}" width="200" height="220">
{% endfor %}
{% endblock %}
post_episode.html
{% extends "personal/header.html" %}
{% load staticfiles %}
{% block content %}
<div class="container-fluid_cartoons">
<h3>{{post_episode.title}}</h3>
<video width="850" height="500" controls>
<source src="{{post_episdoe.video.url}}" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
{% endblock %}
Issues
- Only cartoons.html is working fine.
Once I click on an individual post the relevant post.html shows all the episode uploaded rather than episodes pertaining to individual post only.
Once I click on an episode, nothing happens.
You should consider creating views.py file rather than using generic views in urls.py. I think issue is with following line
url(r'^(?P<pk>\d+)$',login_required(ListView.as_view(queryset=post_episode.objects.filter(post_id=1).order_by("-date"),template_name="cartoons/post.html"))),
Here, If my guess is correct, you are trying to pass id of post model from url to view. But to make ListView accept url kwargs (post_id) you have to write another view in views.py. Maybe something like below.
class EpisodeListView(ListView):
template_name = 'cartoons/post.html'
def get_queryset(self):
return post_episode.objects.filter(post_id=self.kwargs['post_id']).order_by("-date")
Then route a url to that view:
from <yourapp.views> import EpisodeListView
from django.contrib.auth.decorators import login_required
url(r'^episodes/(?P<pk>\d+)$',login_required(EpisodeListView.as_view())