can't implement django inside html - python

I have a problem where I can't use my Django variables inside Html
This is my code :
models.py
from django.db import models
from django.urls import reverse
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255, unique=True)
created = models.DateTimeField(auto_now_add=True)
content = models.TextField(default="---")
H_price = models.IntegerField(default=0)
L_price = models.IntegerField(default=0)
remaining = models.IntegerField(default=0)
original_price = models.IntegerField(default=0)
Ended = models.BooleanField(default=False)
Published = models.BooleanField(default=True)
class Meta:
ordering = ['-created']
def __unicode__(self):
return u'%s'% self.title
def get_absolute_url(self):
return reverse('Products.views.post', args=[self.slug])
Views.py
from django.shortcuts import render
from .models import Post
# Create your views here.
def index(request):
posts=Post.objects.all()
return render(request, 'Index.html', {"Posts": posts})
def post(request):
return
Index.html
<h1>This is just a title </h1>
{% for post in posts %}
<div>
<h3> {{ post.title }}</h3>
<h3> {{ post.content }}</h3>
</div>
{% endfor %}
I know this isn't the best way to do Html but the goal is just to get it to work then I will style it with css and make everything Look Clean When i run the server i only get "this is just a title"
Any suggestions to help me fix it will be apreciated
Note that I am a begginer in django

Variables in the Django template language are case sensitive. You use {% for post in posts %} in your template, therefore you need to use posts not Posts in your view.
return render(request, 'Index.html', {"posts": posts})

Related

I want to add like unlike feature to my blog site, everythin is okay there, like and unlike objects are being created.. But I'm getting NoReverseMatch

I want to add like unlike feature to my blog site, everythin is okay there, like and unlike objects are being created.. But I'm getting NoReverseMatch when I'm clicking the Like and Unlike..and the problem is I can't figure it out why I'm getting this...my models.py, views.py, urls.py, blog_page.html...all are attatched here..
plz try help me solve this
**models.py**
from email.policy import default
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Blog(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=200, verbose_name="Put a Title")
blog_content = models.TextField(verbose_name="What is on your mind")
blog_image = models.ImageField(upload_to="blog_images", default = "/default.png")
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
class Comment(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name = "blog_comment" )
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name = "user_comment")
comment = models.TextField()
comment_date = models.DateField(auto_now_add=True)
def __str__(self):
return self.comment
class Like(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name = "blog_liked")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name = "user_liked")
class Unlike(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name = "blog_unliked")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name = "user_unliked")
**views.py**
from django.shortcuts import render
from . models import Blog, Comment, Like, Unlike
# Create your views here.
def home(request):
blogs = Blog.objects.all()
context = {'blogs': blogs}
return render(request, 'blog_app/home.html', context)
def blog_view(request, pk):
blog = Blog.objects.get(id=pk)
context = {"blog": blog}
return render(request, 'blog_app/blog_page.html', context)
def like(request, pk):
blog = Blog.objects.get(id=pk)
user = request.user
liked, like = Like.objects.get_or_create(blog=blog, user=user)
context = {"liked" : liked}
return render(request, "blog_app/blog_page.html", context)
def unlike(request, pk):
blog = Blog.objects.get(id=pk)
user = request.user
unliked, unlike = Unlike.objects.get_or_create(blog=blog, user=user)
context = {"unliked" : unliked}
return render(request, "blog_app/blog_page.html", context)
**urls.py**
from django.urls import path
from blog_app import views
urlpatterns = [
path("", views.home, name='home'),
path("blog_page/<str:pk>/", views.blog_view, name='blog_page'),
path("like/<str:pk>/", views.like, name="like"),
path("unlike/<str:pk>/", views.unlike, name="unlike"),
]
**blog_page.html**
{% extends "main.html" %}
{% load static %}
{% block content %}
<div style="text-align:center;">
<h2>{{blog.title}}</h2>
<img src="{{blog.blog_image.url}}" alt="" width="630px" height="300px">
</div>
<div style="text-align:center;">
{{blog.blog_content|linebreaks}}
</div>
{% if liked %}
<h4>Unlike</h4>
{% else %}
<h4> Like </h4>
{% endif %}
{% endblock content %}
Your URLs are expecting a string value for blog_id but you are passing them an int in {% url 'unlike' blog.id %} Try changing your URL file to expect an int, and you should be able to look it up more successfully.
path("blog_page/<int:pk>/", views.blog_view, name='blog_page'),
path("like/<int:pk>/", views.like, name="like"),
path("unlike/<int:pk>/", views.unlike, name="unlike"),
Also, as you are using the same page template for the like and unlike view, you will need to pass the blog element in the context again to make links work on those pages, eg,
context = {"liked" : liked, "blog", blog}

Django: How to filter and display posts from categories on a page

I'm new to Django and have build a simple application that includes posts. I want to display posts that are associated with certain categories on one page. I did quite a bit of research online but can't seem to make it work. I think the problem is in my views.py
I guess there's something wrong with the get_queryset function in CategoryListView.
'''
models.py
'''
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ForeignKey(
'Category',
on_delete=models.SET_NULL,
null=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(max_length=150, unique=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('post-category', kwargs={'pk': self.pk})
'''
views.py
'''
from django.views.generic import ListView
from .models import Post, Category
class CategoryListView(ListView):
model = Post
template_name = 'posts/post_category.html'
def get_queryset(self):
category = get_object_or_404(Category, id=self.kwargs.get('category__name'))
return Posts.objects.filter(category_name=category)
'''
urls.py
'''
from .views import CategoryListView
urlpatterns = [
# urlpatterns for other pages left out for better readability
CategoryListView.as_view(), name='post-category')
]
The code gives me a 404 and the message that no Category matches my query.
The get_queryset [Django-doc] function should return something like:
class CategoryListView(ListView):
# ...
def get_queryset(self):
return Post.objects.filter(category_id=self.kwargs.get('pk'))
Furthermore in your url, you will need to use a pattern with a pk parameter, like:
urlpatterns = [
path('category/<int:pk>', CategoryListView.as_view(), name='post-category')
]
That being said, if you want to display information about the category, it might make more sense to make it a DetailView [Django-doc], and then query the relation in reverse, like:
class CategoryDetailView(DetailView):
model = Category
context_object_name = 'category'
template_name = 'posts/post_category.html'
and in the template, you can render data with:
Category name: {{ category.name }}
{% for post in category.post_set.all %}
post: {{ post.title }}
{% endfor %}
This works, but how dow I reverse the order of it to always show the latest post first?
Category name: {{ category.name }}
{% for post in category.post_set.all %}
post: {{ post.title }}
{% endfor %}

Displaying all the posts of user in Django

I want to get all posts that a user send. For example user: admin, it will show admin's posts. I write some code, but probably I made a mistake and I got an error.
The error that I get:
AttributeError at /index_page/
'WSGIRequest' object has no attribute 'models'
Here is my code:
views.py
def index_page(request):
logged_in_user = request.models.author
logged_in_user_posts = Post.objects.filter(author=user)
return render(request, 'blog/post_list.html', {'posts': logged_in_user_posts})
models.py
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = RichTextField()
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
post_list.html
<div>
{% for post in posts %}
Username: {{ post.author.username }}
Post: {{ post.text }}
<br>
{% endfor %}
Where is my mistake?
The error already hints to the line:
logged_in_user = request.models.author
A request object has no models attribute. It has a .user attribute that specifies the logged in user, so you can use:
logged_in_user = request.user
There is another error: you use Post.objects.filter(user=user), but there is no user variable either, there is a logged_in_user variable. So you can fix the view with:
def index_page(request):
logged_in_user_posts = Post.objects.filter(author=request.user)
return render(request, 'blog/post_list.html', {'posts': logged_in_user_posts})
Extra notes:
since you need a user, it makes sense to decorate the function with the login_required decorator [Django-doc]; and
Since Django allows you to change the User model, it might be beneficial to use the standard way to refer to the user model [Django-doc]. If you later change your mind and implement another user model, the creating migrations will automatically let the relations refer to the new model.
The two comments above are not strictly necessary to let it work. But it is what I think are good practices when developing Django apps (although of course these can be a bit "opinion-based").
The issue is in your view, request object does not contain your models.The view should be like below,
def index_page(request):
logged_in_user = request.user
logged_in_user_posts = Post.objects.filter(author=logged_in_user)
return render(request, 'blog/post_list.html', {'posts': logged_in_user_posts})
I am answering a little bit late , But may be it help someone later . you can use class-based views . In your case
views.py :
class UserPostListView(ListView):
model = Post
template_name = 'app_name/template_name.html'
context_object_name = 'posts'
def get_queryset(self):
user = get_object_or_404(User,username=self.kwargs.get('username'))
return Post.objects.filter(author=user)
and in your urls.py :
path('user/<str:username>', views.UserPostListView.as_view(), name='user-posts'),
and then in your template :
{% block content%}
<h1> My files </h1>
{% for post in posts %}
{% endfor %}
{% endblock %}

django specific user content/data

I'm trying to display specific content/data based on a logged in user. I want to display only their info. This is what I've tried but I can't get it to work.
views.py
class DemoView(TemplateView):
template_name = 'demographics/demographics.html'
def get(self, request):
demos = Demographics.objects.filter(user=request.user)
context = {
'demos': demos,
}
return render(request, self.template_name, context)
models.py
class Demographics(models.Model):
first_name = models.CharField(max_length=50, null=True)
middle_name = models.CharField(max_length=50, null=True)
last_name = models.CharField(max_length=50, null=True)
user = models.ForeignKey(User, null=True)
HTML
{% if demos %}
{% for demographics in demos %}
<p>First Name</p> {{ demographics.first_name }}
{% endfor %}
{% else %}
<h3>you dont have demo yet</h3>
{% endif %}
I feel like I'm close. What am I missing?
I think the issue may be that you are filtering out all answers from your queryset because the content of request.user is not quite a match for a 'user' object. I don't know why they wouldn't match, but in my code I use:
User.objects.get(username = request.user.username)
I think debugging using pdb will help why the get is not rendering the data properly but if you know how django templateview class handles the context data, you have to modify the code a bit. Here I used get_context_data instead of get and hope this time it will work.
class DemoView(TemplateView):
template_name = 'demographics/demographics.html'
def get_context_data(self, **kwargs):
context = super(DemoView, self).get_context_data(**kwargs)
demos = Demographics.objects.filter(user=self.request.user)
context['demos'] = demos
return context
Also you can check if the table Demographics has the data for the selected user.
full Answer:
Views.py
class DemoView(TemplateView):
template_name = 'demographics/demographics.html'
def get(self, request, *args, **kwargs):
demos = Demographics.objects.filter(user=User.objects.get (username=request.user))
context = {
'demos': demos,
}
return render(request, self.template_name, context)
HTML:
{% if demos %}
{% for demographics in demos %}
<p>First Name</p> {{ demographics.first_name }}
{% endfor %}
{% else %}
<h3>you dont have demo yet</h3>
{% endif %}
urls.py
url(r'^test/', views.DemoView.as_view()),
admin.py
admin.site.register(Demographics)
models.py
class Demographics(models.Model):
first_name = models.CharField(max_length=50, null=True)
middle_name = models.CharField(max_length=50, null=True)
last_name = models.CharField(max_length=50, null=True)
user = models.ForeignKey(User, null=True)
Go to django admin, check your objects, and make sure you're logged in to the account that has demographic objects associated with it.
The above setup works for me, if it doesn't work for you, you're most likely logged in as a user which doesn't have any demographic objects associated with it.
Also, don't name your models as plural, it should be Demographic, because it is a representation of one object. When you filter in views, you name the variable demographics (plural), because the query returns more than one object.

Django listview with multiple models and filters

Django newbie here...
I have three models which I'm currently wrestling with and I obtained a desired solution. However, the solution is certainly not efficient nor good practice. I just don't know enough to adequately implement what I want.
Here are the models...
basics/models.py
class Tag(models.Model):
slug = models.SlugField(max_length=200, unique=True)
def __unicode__(self):
return self.slug
def get_absolute_url(self):
return reverse("tag_index", kwargs={"slug": self.slug})
class post(models.Model):
title = models.CharField(max_length = 180)
// a bunch of other fields here
tags = models.ManyToManyField(Tag)
def get_absolute_url(self):
return reverse("post_detail", kwargs={"slug": self.slug})
def __unicode__(self):
return self.title
class Meta:
verbose_name = "Blog Post"
verbose_name_plural = "Blog Posts"
ordering = ["-created"]
projects/models.py
class project(models.Model):
projectTitle = models.CharField(max_length=150, null=False)
projectTag = models.OneToOneField(Tag, primary_key=True)
description = MarkdownField()
def __unicode__(self): # __unicode__ on Python 2
return self.projectTitle
class Meta:
verbose_name = "Project"
verbose_name_plural = "Projects"
Now... what I would like to do is to create an adequate view, which passes to my template only the posts which are tagged with the project tags rather than all posts as it is currently doing.
projects/views.py
class projectFeed(generic.ListView):
queryset = project.objects.all()
template_name = "projects.html"
paginate_by = 5
def get_context_data(self, **kwargs):
context = super(projectFeed, self).get_context_data(**kwargs)
# slug = self.kwargs['projectTag']
# tag = Tag.objects.get(slug=slug)
context['posts'] = post.objects.all()#filter(tags=tag)
return context
As you can see, I tried some stuff that I used for creating the view for displaying all posts with a certain tag but I couldn't get it to work here.
projects/templates/projects.html
{% for project in project_list %}
<div class='postContent'>
<!-- project stuff here -->
{% for post in posts %}
{% if project.projectTag in post.tags.all %}
<p> {{ post.title }} </p>
{% endif %}
{% endfor %}
</div>
{% endfor %}
Ideally... I want to pass a nested list of sorts where each project in the project_list has an associated list of posts which I can iterate over in the inner for loop without needing to check the tags. That is, I want to filter and arrange the data in the view method/class OR another more efficient place.
You can get list of related post using next relate managers:
posts = project.projectTag.post_set.all()
Why won't you try using it in your template
{% for project in project_list %}
<!-- project stuff hete -->
{% for post in project.projectTag.post_set.all %}
<!-- post stuff goes here -->
{% endfor %}
{% endfor %}
But to reduce number of sql queries you will have to override get_queryset method of your ListFilter:
def get_queryset(self):
return super(projectFeed, self).get_queryset()
.select_related('projecttag')
.prefetch_related('projecttag__post_set')

Categories

Resources