How can I access a function from model in template in Django? - python

I have a model 'Post' and this has a function 'total_likes' that counts all the likes on a post. How can i access this function inside my template to show the number of likes? Thank you!
Model:
class Post(models.Model):
created_date = models.DateTimeField()
title = models.CharField(max_length=100)
profile_image = models.ImageField(upload_to='poze', blank=True, null=True)
text = models.CharField(max_length=1000, default='Nimic', blank=True)
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
likes=models.ManyToManyField(UserProfile,related_name='likes',blank=True )
def total_likes(self):
return self.likes.count()
View:
class ShowPosts(APIView):
renderer_classes = [TemplateHTMLRenderer]
template_name = 'mainPage.html'
def get(self, request):
posts = Post.objects.all()
serializer = PostSerializer(posts, many=True)
return Response({'posts': serializer.data})
Template:
{% extends 'base2.html' %}
{% load static %}
{% load rest_framework %}
{% load crispy_forms_tags %}
<form action="{% url 'like_post' %}" method="post">
{% csrf_token %}
<button type="submit" name="post_id" value="{{ post.id}}">Like {{"How can I access the 'total_likes' function ?'}}</button>
</form>
{% endfor %}
{% endblock %}

Just reference the method like any other attribute. Since it didn't take any parameters, Django will call it automatically.
{{ post.total_likes }}

Just like you passed {{post.id}}, call the function before you render the template, and pass the arg to it

Related

Data not rendering from django database to html

Data from database to html is not rendering. The static data is rendering but unfortunately the database data is not rendering no error occurs, and page is also rendering but data is not rendering from database to the page.
Html doc
{% extends "base.html" %}
{% load static %}
{% block title %}
All Tractors
{% endblock %}
{% block content%}
<section id="all_events">
<h1>All Tractors</h1>
<h1>{{posts.implementation}} hi</h1>
<br>
<ul>
{% for posts in post %}
{% include "tractor/includes/singlePost.html" %}
{% endfor %}
</ul>
</section>
{% endblock %}
Vews.py
from django import forms
from django.contrib.auth.models import User
from django.shortcuts import render, redirect
from .models import Post, Farmer
# Create your views here.
from django.http import HttpResponseRedirect
# Create your views here.
def starting_page(request):
return render(request,"tractor/index.html")
def posts(request):
qs = Post.objects.all()
context = {"posts":qs}
return render(request,"tractor/all-post.html",context)
This is the Models.py file:
from django.db import models
from django.core.validators import MinLengthValidator
from django.db.models.signals import pre_save
# Create your models here.
from .utils import unique_slug_generator
class Farmer(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
phone =models.CharField(max_length=10)
address = models.TextField(max_length=200)
email_address = models.EmailField()
def full_name(self):
return f"{self.first_name} {self.last_name}"
def __str__(self):
return self.full_name()
class Post(models.Model):
tractor_price = models.IntegerField(max_length=150)
implementation = models.CharField(max_length=50)
purchase_date = models.DateField(auto_now=False)
slug = models.SlugField(unique=True, db_index=True, null=True,blank=True)
tractor_company = models.CharField(max_length=50)
tractor_model = models.CharField(max_length=50)
description = models.TextField(validators=[MinLengthValidator(10)])
date = models.DateField(auto_now=False)
farmer = models.ForeignKey(
Farmer, on_delete=models.SET_NULL, null=True, related_name="posts")
def __str__(self):
return self.implementation
Try this:
{% load static %}
{% block title %}
All Tractors
{% endblock %}
{% block content%}
<section id="all_events">
<h1>All Tractors</h1>
<ul>
{% for post in posts %}
<h1>{{post.implementation}} hi</h1>
<br>
{% include "tractor/includes/singlePost.html" %}
{% endfor %}
</ul>
</section>
{% endblock %}
It should be {% for post in posts %}

How can I get the user profile detail to work properly in django

I am trying to include a profile feature in a simple blog site. I have created a profile model using the one to one link for the user field, also created a function view for the profile detail with corresponding template name but i keep getting a 404 error.
user = models.OneToOneField(User, on_delete=models.SET_NULL, null=True)
username = models.CharField(max_length=15, default='Anonymous')
dp = models.ImageField(null=True)
country = models.CharField(max_length=20, null=True)
age = models.IntegerField(null=True)
joined = models.DateTimeField( auto_now_add=True)
class Meta:
ordering = ['joined']
def __str__(self):
return self.username
def get_absolute_url(self):
return reverse('profile_detail', args=[str(self.id)])
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()```
views.py
def profile_detail(request, pk):
user = get_object_or_404(User, pk=pk)
context = {'user': user}
return render(request, 'milk/profile_detail.html', context)
profile_detail.html
{% extends 'milk/base.html' %}
{% block title %}
{% endblock %}
{% block content %}
<h2>{{ user.get_full_name }}</h2>
<ul>
<li>Username: {{ user.username }}</li>
<li>Location: {{ user.profile.country }}</li>
<li>Age: {{ user.profile.age }}</li>
</ul>
{% endblock %}
template referencing
<em>{{user.get_username }}</em>
urls.py
path('profile/<int:pk>/', views.profile_detail, name='profile_detail'),
you can display current user info like this without passing through context
{% extends 'milk/base.html' %}
{% block title %}
{% endblock %}
{% block content %}
<h2>{{ request.user.profile.get_full_name }}</h2>
<ul>
<li>Username: {{ request.user }}</li>
<li>Location: {{ request.user.profile.profile.country }}</li>
<li>Age: {{ request.user.profile.profile.age }}</li>
</ul>
{% endblock %}
or
instead of 'get_object_or_404' try
user = User.objects.get(id=pk)

I don't work comments and forms are not displayed

I'm trying to make comments on the site, but when I start the server, I do not see the forms. I create a simple blog in which a person can post likes and comment, but the problem is that when i add a comment form, they simply do not appear.
P.S
And excuse me for my English I am from another country and I don’t know English very well
post.html main template
{% extends "ShapeHtml/wrapper.html" %}
{% block content %}
<div class="panel panel-default">
<div class="panel-heading">
<h1 class=" text-info">{{object.title}}</h1>
</div>
<div class="panel-body">
<p> {{object.post|safe|linebreaks}} </p>
<h3 align="right" class=" text-info"> Опубликованно: {{articles.date|date:"d-m-Y в H:i"}}</h3>
</div>
<h4>Comments</h4>
<form action="{% url '' %}" method="post">
{% csrf_token %}
{% if CommentModel %}
{% for CommentModel in comments %}
{{ CommentModel.WhoAreYou }} <br>
{% endfor %}
{% endif %}
{{ form }}
<input type="submit" value="Submit">
</form>
{% endblock %}
views.py
from .forms import CommentForm
class ArticlesList(ListView):
model = Articles
template_name = 'news/posts.html'
class ArticleDetail(DetailView):
model = Articles
template_name = 'news/post.html'
def GetComments(request):
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(request.path_info)
else:
form = CommentForm()
comments = CommentModel.objects.all()
return render(request, 'news/post.html', {'form': form, 'comments': comments})
urls.py
urlpatterns=[
path('', ArticlesList.as_view(), name='articles_list'),
path('<int:pk>/', ArticleDetail.as_view(), name='article_detail'),
path('aboutUs', views.aboutUs, name='aboutUs'),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
models.py it's models for posts and for comments
from django.db import models
class Articles(models.Model):
title = models.CharField(max_length= 200)
post = models.TextField()
date = models.DateTimeField()
img = models.ImageField(upload_to='', default="default_value")
def __str__(self):
return self.title
class CommentModel(models.Model):
WhoAreYou = models.CharField(max_length=100)
forms.py form for fields
class CommentForm(ModelForm):
class Meta:
model = CommentModel
fields = ('WhoAreYou',)
you've write class CommentForm(forms.ModelForm) in forms.py:
class CommentForm(forms.ModelForm):
comment = forms.CharField()
class Meta:
model = CommentModel
fields = ('WhoAreYou',)
I guess it'll works.

Django 1.7 | Comment Form With Blog Post

I working on a blog using Django 1.7.
I want to include a comment form with each blog post but unsure how to do that.
Here is my code:
Models:
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
slug = models.SlugField(unique=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Category, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, unique=True)
body = models.TextField()
posted = models.DateTimeField(db_index=True, auto_now_add=True)
category = models.ForeignKey(Category)
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
def __unicode__(self):
return '%s' % self.title
class Comment (models.Model):
comment_body = models.TextField()
commented_on = models.DateTimeField(db_index=True,auto_now=True)
commenter = models.ForeignKey(User)
post = models.ForeignKey(Post)
def __unicode__(self):
return '%s' % self.comment_body
class Tag (models.Model):
title = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, unique=True)
post = models.ManyToManyField(Post)
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Tag, self).save(*args, **kwargs)
def __unicode__(self):
return '%s' % self.title
Views:
def blog_post(request, blog_post_slug):
post_detail = Post.objects.get(slug=blog_post_slug)
comments = Comment.objects.filter(post=post_detail.id)
tags = Tag.objects.filter(post=post_detail.id)
context_dict = {'post': post_detail, 'slug': blog_post_slug, 'comments':comments, 'tags':tags}
response = render(request,'blog/blog_post.html', context_dict)
return response
Template:
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}{{ post.title }}{% endblock %}
{% block body_block %}
<div class="container">
<div class="post-preview">
{% if post %}
<div>
<h2>{{ post.title }}</h2>
<small>{{ post.category }}</small>
<p class="post-meta">{{ post.posted }}</p>
<p>{{ post.body }}</p>
<h3>Comments</h3>
{% if comments %}
{% for comment in comments %}
<h5> {{ comment.commenter | capfirst }}</h5>
<p> {{ comment.comment_body }}</p>
<small>{{ comment.commented_on }}</small>
<hr>
{% endfor %}
{% else %}
<small>No comments Yet </small>
{% endif %}
<h3>Tags</h3>
{% if tags %}
{% for tag in tags %}
<span> {{ tag.title }},</span>
{% endfor %}
{% else %}
<small>Without Tags! </small>
{% endif %}
</div>
{% else %}
<strong>No such post</strong>
{% endif %}
</div>
</div>
{% endblock %}
I am using form.py to generate forms but unsure what to do in this scenario.
I just want that viewer can submit his comments on the page of blog post.
(This is answer was probably based off the Django tutorials at djangoproject.com and maybe elsewhere)
You can simply define a form for commenting in form.py, make a new instance of it in your blog_post() function, and include the newly minted form in context_dict. Then in the template, use {{ thenameyougiveyourforminthecontext }} to include a simple version of the form.
Then, in the blog_post() method in views.py, handle the form's submission. The Django website (specifically this page) describes how to handle the form's submission. In the form handling, you can create a new Comment object with the dictionary entries in form.cleaned_data (assuming you have validated it using form.is_valid() first) and save it.
This is a very brief overview of how to do this. Please look at the url I linked to truly understand how to do this.

How to make generic ListView only show user's listing?

I'm new to Django and I'm utilizing class-based views for the first time. I want to use the generic ListView to show a list of "tables" owned by a user. And so far I've gotten it to display ALL the tables in the database. But I only want it to show tables for the logged in user.
this is what my view looks like:
from django.shortcuts import render
from django.http import HttpResponse
from django.views import generic
from vtables.models import Vtable
class TableListView(generic.ListView):
model = Vtable
context_object_name = 'table_list'
def get_context_data(self, **kwargs):
context = super(TableListView, self).get_context_data(**kwargs)
return context
And this is what my model looks like:
from django.db import models
from django.contrib.auth.models import User
class Vtable(models.Model):
user = models.ForeignKey(User)
table_name = models.CharField(max_length=200)
added_date = models.DateTimeField('date added')
class Vdata(models.Model):
table_id = models.ForeignKey(Vtable)
table_pk = models.IntegerField()
column_1 = models.CharField(max_length=200)
column_2 = models.CharField(max_length=200)
added_date = models.DateTimeField('date added')
I'll admit, I'm not sure what this line is doing:
context = super(TableListView, self).get_context_data(**kwargs)
But I suspect this is what I need to change? Or do I have to go into my template and do an if statement there? Maybe something like: {% if request.user == vtable.user %}?
EDIT: here is my template:
{% extends "base.html" %}
{% load staticfiles %}
{% block content %}
{% if request.user.is_authenticated %}
<img src="{{ request.user.profile.profile_image_url }}"/>
Logout
{% if request.user.first_name or request.user.last_name %}
{{ request.user.first_name }} {{ request.user.last_name }}
{% else %}
{{ request.user.username }}
{% endif %}
{% if request.user.profile.account_verified %}
(verified)
{% else %}
(unverified)
{% endif %}
<h1>Tables</h1>
<ul>
{% for vtable in table_list %}
<li>{{ vtable.user }}, {{ vtable.table_name }}</li>
{% endfor %}
</ul>
{% else %}
Login
{% endif %}
{% endblock %}
perhaps, overriding get_queryset():
def get_queryset(self):
return self.model.objects.filter(user=self.request.user)

Categories