Show data after dropdown selection - python

I am struggling with my code. I want to show data from a specific user on screen. When the second dropdown is selected with the user from a specific group, I want his records to be shown on screen. But what ever I try, the data stays the same from one user. In a later stadium I want to make an Else and say if there is no data, that there is no data of the person. Should I do something with a jquery, or is there an easier way to solve this?
The first dropdown is the group, the second dropdown the user.
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class DisplayGroups(models.Model):
group_name = models.CharField(max_length=200)
def __str__(self):
return self.group_name
class DisplayUsername(models.Model):
username = models.CharField(max_length=100)
def __str__(self):
return self.username
class CijferLijst(models.Model):
name = models.CharField(max_length=200, default='')
vak1 = models.CharField(max_length=200, default='')
cijfer1 = models.DecimalField(max_digits=3, decimal_places=1, default='1.0')
vak2 = models.CharField(max_length=200, default='')
cijfer2 = models.DecimalField(max_digits=3, decimal_places=1, default='1.0')
username = models.ForeignKey(User, on_delete=models.CASCADE, default='')
def __str__(self):
return '%s %s %s %s %s %s'%(self.name, self.vak1, self.cijfer1, self.vak2, self.cijfer2, self.username)
bekijk.html
{% extends 'home/base.html' %}
{% block title %}Cijfers studenten{% endblock %}
{% block javascript %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function()
{
var $select1 = $('#groupdd1'),
$select2 = $('#userdd1'),
$options = $select2.find('option');
$select1.on('change', function()
{
$select2.html($options.filter('[value="'+this.value+'"]'));
}).trigger('change');
});
</script>
{% endblock %}
{% block content %}
{% if user.is_staff %}
<h1>Studentresultaten</h1>
<select id="groupdd1">
<option disabled="true" selected>Kies een groep</option>
{% for result in DisplayGroups %}
<option>{{result}}</option>
{% endfor %}
</select>
<select id="userdd1">
<option disabled="true" selected>Kies een gebruiker</option>
{% for result in DisplayUsername %}
<option value="{{result.username}}">{{result}}</option>
{% endfor %}
</select>
{% endif %}
<br/>
{% for antwoord in CijferLijst %}
<h2>{{antwoord.name}}</h2>
<div class="container px-4">
<div class="row justify content-start gx-5">
<div class="col-5 border bg-light"><strong>Vaknaam</strong></div>
<div class="col-5 border bg-light"><strong>Cijfer</strong></div>
</div>
<div class="row gx-5 justify-content-start">
<div class="col-5 border bg-light">{{antwoord.vak1}}</div>
<div class="col-5 border bg-light">{{antwoord.cijfer1}}</div>
</div>
<div class="row gx-5 justify-content-start">
<div class="col-5 border bg-light">{{antwoord.vak2}}</div>
<div class="col-5 border bg-light">{{antwoord.cijfer2}}</div>
<div class="col-5 border bg-light">{{antwoord.username}}</div>
</div>
</div>
{% endfor %}
{% endblock %}
views.py
from django.shortcuts import render, redirect
from .models import DisplayGroups, DisplayUsername, CijferLijst
from .forms import Grades
from django.contrib.auth.models import User, Group
# Create your views here.
def index(request):
response = redirect('/login')
return response
def home(response):
return render(response, "home/home.html")
def bekijk(request):
DisplayGroup = Group.objects.all()
print(DisplayGroup)
DisplayNames = User.objects.all()
print(DisplayNames)
Cijfer = CijferLijst.objects.all()
print(Cijfer)
return render(request, "home/bekijk.html",
{"DisplayGroups": DisplayGroup, "DisplayUsername": DisplayNames, "CijferLijst": Cijfer})
def cijfers(request):
if request.method == "POST":
form = Grades(request.POST)
if form.is_valid():
form.save()
print(form)
return redirect('gelukt')
else:
form = Grades()
return render(request, "home/cijfers.html", {"form":form})
def done(response):
return render(response, "home/gelukt.html")
forms.py
from django import forms
from .models import CijferLijst
from django.contrib.auth.models import User
class Grades(forms.ModelForm):
name = forms.CharField(max_length=200)
vak1 = forms.CharField(max_length=200)
cijfer1 = forms.DecimalField(max_digits=3, decimal_places=1)
vak2 = forms.CharField(max_length=200)
cijfer2 = forms.DecimalField(max_digits=3, decimal_places=1)
username = forms.ModelChoiceField(queryset=User.objects.all())
check = forms.BooleanField()
class Meta:
model = CijferLijst
fields = ['name', 'vak1', 'cijfer1', 'vak2', 'cijfer2', 'username']
Thanks in advance.

Related

django database is not saving data of contact from details which i have entered

I'm new to dajngo projects and I have created a blog which has app named as "blog".Everything went all right and I stuck at conatct from.when I sumbmit details in contact from and go to djando admin database the contact details are not saved here.
This is my contact.html code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<title>contact us</title>
</head>
{% load static %}
<body style="background-image: url('{% static " img/contact.jpg" %}');background-size: cover;">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
<div class="container my-3" style="padding:70px 0">
<h3>Contact Us</h3>
<form method="post" action="{% url "contact" %}" > {% csrf_token %}
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" name='name' placeholder="Enter Your Name">
</div>
<div class="form-group">
<label for="name">Email</label>
<input type="email" class="form-control" id="email" name='email' placeholder="Enter Your Email">
</div>
<div class="form-group" >
<label for="name">Phone</label>
<input type="tel" class="form-control" id="phone" name='phone' placeholder="Enter Your Phone Number">
</div>
<div class="form-group" >
<label for="desc">How May We Help You?</label>
<textarea class="form-control" id="desc" name='desc' rows="3"></textarea>
</div>
<button style=" margin-top: 25px;" type="submit" class="btn btn-success">Submit</button>
</form>
</div>
</body>
</html>
This is post_detail.html
{% extends 'base.html' %} {% block content %}
{% load crispy_forms_tags %}
<div class="container">
<div class="row">
<div class="col-md-8 card mb-4 mt-3 left top">
<div class="card-body">
<h1>{% block title %} {{ post.title }} {% endblock title %}</h1>
<p class=" text-muted">{{ post.author }} | {{ post.created_on }}</p>
<p class="card-text ">{{ post.content | safe }}</p>
</div>
</div>
{% block sidebar %} {% include 'sidebar.html' %} {% endblock sidebar %}
<div class="col-md-8 card mb-4 mt-3 ">
<div class="card-body">
<!-- comments -->
<h2>{{ comments.count }} comments</h2>
{% for comment in comments %}
<div class="comments" style="padding: 10px;">
<p class="font-weight-bold">
{{ comment.name }}
<span class=" text-muted font-weight-normal">
{{ comment.created_on }}
</span>
</p>
{{ comment.body | linebreaks }}
</div>
{% endfor %}
</div>
</div>
<div class="col-md-8 card mb-4 mt-3 ">
<div class="card-body">
{% if new_comment %}
<div class="alert alert-success" role="alert">
Your comment is awaiting moderation
</div>
{% else %}
<h3>Leave a comment</h3>
<form method="post" style="margin-top: 1.3em;">
<!--{{ comment_form.as_p }}-->
{{ comment_form | crispy }}
{% csrf_token %}
<button type="submit" class="btn btn-primary btn-lg">Submit</button>
</form>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock content %}
This is admin.py
from django.contrib import admin
from .models import Post,Comment
from .models import Contact
from django_summernote.admin import SummernoteModelAdmin
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'slug', 'status', 'created_on')
list_filter = ("status",)
search_fields = ['title', 'content']
prepopulated_fields = {'slug': ('title',)}
#admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
list_display = ('name', 'body', 'post', 'created_on', 'active')
list_filter = ('active', 'created_on')
search_fields = ('name', 'email', 'body')
actions = ['approve_comments']
def approve_comments(self, request, queryset):
queryset.update(active=True)
class PostAdmin(SummernoteModelAdmin):
summernote_fields = ('content',)
admin.site.register(Post, PostAdmin)
admin.site.register(Contact)
This is models.py
from django.db import models
from django.contrib.auth.models import User
STATUS = (
(0,"Draft"),
(1,"Publish")
)
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
updated_on = models.DateTimeField(auto_now= True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
def get_absolute_url(self):
from django.urls import reverse
return reverse("post_detail", kwargs={"slug": str(self.slug)})
class Comment(models.Model):
post = models.ForeignKey(Post,on_delete=models.CASCADE,related_name='comments')
name = models.CharField(max_length=80)
email = models.EmailField()
body = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=False)
class Meta:
ordering = ['created_on']
def __str__(self):
return 'Comment {} by {}'.format(self.body, self.name)
class Contact(models.Model):
msg_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
email = models.CharField(max_length=70, default="")
phone = models.CharField(max_length=70, default="")
desc = models.CharField(max_length=500, default="")
def __str__(self):
return self.name
This is urls.py
from . import views
from django.urls import include
from django.urls import path
from .feeds import LatestPostsFeed, AtomSiteNewsFeed
urlpatterns = [
path("feed/rss", LatestPostsFeed(), name="post_feed"),
path("feed/atom", AtomSiteNewsFeed()),
path("<slug:slug>/", views.post_detail, name="post_detail"),
path("", views.PostList.as_view(), name="home"),
path("about.html",views.about,name='about'),
path("contact.html",views.contact,name='contact'),
path("blb.html",views.blb,name='blb '),
path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'),
]
This is view.py
from .models import Post
from django.views import generic
from .forms import CommentForm
from django.shortcuts import render, get_object_or_404
from .models import Contact
def about(request):
return render(request,'about.html',{})
def contact(request):
return render(request,'contact.html',{})
def blb(request):
return render(request,'blb.html',{})
def Contact(request):
if request.method == "POST":
name = request.POST.get['name','']
email = request.POST.get['email','']
phone = request.POST.get['phone','']
content = request.POST.get['content','']
contact = Contact(name=name, email=email, phone=phone, content=content)
contact.save()
return render(request, "contact.html")
class PostList(generic.ListView):
queryset = Post.objects.filter(status=1).order_by("-created_on")
template_name = "index.html"
paginate_by = 3
class PostDetail(generic.DetailView):
model = Post
template_name = 'post_detail.html'
def post_detail(request, slug):
template_name = 'post_detail.html'
post = get_object_or_404(Post, slug=slug)
comments = post.comments.filter(active=True)
new_comment = None
# Comment posted
if request.method == 'POST':
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
# Create Comment object but don't save to database yet
new_comment = comment_form.save(commit=False)
# Assign the current post to the comment
new_comment.post = post
# Save the comment to the database
new_comment.save()
else:
comment_form = CommentForm()
return render(request, template_name, {'post': post,
'comments': comments,
'new_comment': new_comment,
'comment_form': comment_form})
This is project urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.sitemaps.views import sitemap
from blog.sitemaps import PostSitemap
sitemaps = {
"posts": PostSitemap,
}
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("blog.urls"), name="blog-urls"),
path("summernote/", include("django_summernote.urls")),
path("sitemap.xml", sitemap, {"sitemaps": sitemaps}, name="sitemap"),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
enter image description here
[1]: https://i.stack.imgur.com/RCOt4.png
First of all you shoudn`t put the name of your html template in urls.py of your app.
i mean these three lines :
path("about.html",views.about,name='about'),
path("contact.html",views.contact,name='contact'),
path("blb.html",views.blb,name='blb '),
you have to for example replace them with
path('contact/',...)
and for better and cleaner code , it`s better to use forms in your app . create forms.py in your app DIR and import your model in your forms.py like this for example :
from django import forms
from .models import Profile
class {model name (Table name)}(forms.ModelForm):
class Meta:
model = {model name (Table name)}
fields = '__all__'
Replace {model name (Table name)} with your model in your models.py.
then in each input filed in your HTML template, for name attr , you shoud use the same name that uses in your models.py fields.
And in your views.py you should do like this:
form = **{form name}**(request.POST or None, request.FILES)
if form.is_valid():
form.save()
return redirect('**{ somewhere :) }**')
return render(request, 'contact.html', {'form': form})
Hope this Answer could help you ;-)

django view dont show anything

I'm working to create an event page in my Django work.
Although I wrote a code to obtain database data when I try to load the front page(from exhibition_view.html), just the exhibition.view_html loads and no article return and does not show in that page.
the weird thing is that seminar_view and exhibition_view are the same, and seminar_view does work!
I tried very much to solve the issue, but had no idea what is happening!
below is my code:
Model.py
from django.db import models
from django.utils import timezone
from tinymce.models import HTMLField
class EventType(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "Event Types"
def get_deleted_event_type():
return EventType.objects.get(name='no-category')
class Event(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published'),
)
EVENT_CHOICES = (
('seminar', 'seminar'),
('exhibition', 'exhibition'),
)
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=250,
unique_for_date='publish', allow_unicode=True, unique=True)
body = HTMLField()
publish = models.DateTimeField(default=timezone.now)
created_on = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
events = models.ForeignKey(EventType, on_delete=models.SET(get_deleted_event_type))
event_type = models.CharField(max_length=15,
choices=EVENT_CHOICES,
default='seminar')
status = models.CharField(max_length=10,
choices=STATUS_CHOICES,
default='draft')
event_index = models.IntegerField()
class Meta:
ordering = ('-publish',)
verbose_name_plural = "Events"
def __str__(self):
return self.title
Views.py
from django.shortcuts import render
from .models import Event
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Q
def seminar_detail(request, slug):
seminars = Event.objects.get(slug=slug)
context = {
'seminars': seminars
}
return render(request, "seminar_detail.html", context)
def exhibition_detail(request, events, slug):
cr1 = Q(events='2')
cr2 = Q(slug=slug)
exhibitions = Event.objects.get(cr1 & cr2)
context = {
'exhibitions': exhibitions
}
return render(request, "exhibition_detail.html", context)
def seminar_view(request):
criterion1 = Q(status='published')
criterion2 = Q(event_type="seminar")
seminars = Event.objects.filter(criterion1 & criterion2).order_by('event_index')
context = {
'seminars': seminars
}
return render(request, "seminar_view.html", context)
def exhibition_view(request):
criterion3 = Q(status='published')
criterion4 = Q(event_type="exhibition")
exhibitions_view = Event.objects.filter(criterion3 & criterion4).order_by('event_index')
context = {
'exhibitions_view': exhibitions_view
}
return render(request, "exhibition_view.html", context)
exhibition_view.html
{% extends 'base.html' %}
{% load static %}
<head>
<title>{% block title %}exhibitions{% endblock %}</title>
</head>
{% block page_content %}
<div class="page" id="page-container" >
<div class="top-bread">
<div class="breadcrumbs">
<ul>
<li class="home">
home
<span>»</span>
</li>
<li class="socialvoice">
<strong>exhibitions</strong>
</li>
</ul>
</div>
</div>
</div>
<div class="page">
<div class="main-container col1-layout">
<div class="main">
<div class="col-main">
<div class="shopbybrand-list">
<div class="brands">
<ul class="col">
{% for myevent in exhibitions_view %}
<li class="box">
<span>
<a href="{% url 'events:exhibition_view' event.slug %}">
<b>
<h2>{{ myevent.title }}<br/>{{ myevent.created_on.date }}</h2>
</b>
</a>
</span>
<b>
<p>
<p style="text-align: justify;">{{ myevent.body | safe | slice:":400" }}</p>
</p>
<a class="button" href="{% url 'events:exhibition_view' myevent.slug %}">
<span>
<span>ادامه مطلب</span>
</span>
</a>
</b>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
</div>
</div><!-- END page -->
{% endblock %}
and my app urls.py:
from django.urls import path
from . import views
from django.urls import re_path
app_name = 'events'
urlpatterns = [
path('seminar/', views.seminar_view, name="seminar_view"),
path('exhibition/', views.exhibition_view, name="exhibition_view"),
re_path(r'seminar/(?P<slug>[-\w]+)/', views.seminar_detail, name="seminar_detail"),
re_path(r'exhibition/(?P<slug>[-\w]+)/$', views.exhibition_detail, name="exhibition_detail"),
]

How can I add a comment to user on an app that has a relationship many-to-many with another model that has a relationship with other?

I get a huge stuck. now I have many of models which has a relationship between them at many apps I 'll explain that as following:
- The first model is (UserProfile) that has (one to one) relation with (User) model
also, I have (UserAsking) that has relation (ForeignKey) with (UserProfile) and last part is (Comment) That has (Many to many) relations with (UserAsking). in this case, I want to make a comment and this comment that has a relationship with UserAsking model. I'm in trouble, how can I do that?
I find that (many-to-many) is different from any another relationship and I can't get the instance as an argument in (Comment) model
if anyone can give me any help?
thank you in advance
account/models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
CHOICE = [('male', 'male'), ('female', 'female')]
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
overview = models.TextField(editable=True, blank=True, default='You have no an Overview yet')
city = models.CharField(max_length=20, blank=False)
phone = models.IntegerField(default=0, blank=True)
sex = models.CharField(max_length=10, default='male', choices=CHOICE)
skill = models.CharField(max_length=100, default='You have no skills yet')
logo = models.ImageField(upload_to='images/', default='images/default-logo.jpg', blank=True)
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(receiver=create_profile, sender=User)
community/models.py
from django.db import models
from account.models import UserProfile
from django.db.models.signals import post_save
CHOICE = [('Technology', 'Technology'), ('Computer Science', 'Computer Science'),
('Lawyer', 'Lawyer'), ('Trading', 'Trading'),
('Engineering', 'Engineering'), ('Life Dialy', 'Life Dialy')
]
class UserAsking(models.Model):
userprofile = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
title = models.CharField(max_length=100, blank=False, help_text='Be specific and imagine you’re asking a question to another person')
question = models.TextField(max_length=500, blank=False, help_text='Include all the information someone would need to answer your question')
field = models.CharField(max_length=20, choices=CHOICE, default='Technology', help_text='Add the field to describe what your question is about')
def __str__(self):
return self.title
class Comment(models.Model):
userasking = models.ManyToManyField(UserAsking)
comment = models.TextField(max_length=500, blank=True)
community/views.py
from django.shortcuts import render, redirect, get_list_or_404
from .forms import UserAskingForm, CommentForm
from .models import UserAsking
from django.contrib.auth.decorators import login_required
#login_required
def user_asking(request):
form = UserAskingForm
if request.method == 'POST':
form = UserAskingForm(request.POST, instance=request.user.userprofile)
if form.is_valid():
asking = form.save(commit=False)
asking.title = form.cleaned_data['title']
asking.question = form.cleaned_data['question']
asking.field = form.cleaned_data['field']
asking = UserAsking.objects.create(userprofile=request.user.userprofile,
title=asking.title,
question=asking.question,
field=asking.field)
asking.save()
return redirect('community:user_questions')
else:
form = UserAskingForm()
return render(request, 'community/asking_question.html', {'form': form})
return render(request, 'community/asking_question.html', {'form': form})
#login_required
def user_questions(request):
all_objects = UserAsking.objects.all().order_by('-title')
all_objects = get_list_or_404(all_objects)
return render(request, 'community/user_questions.html', {'all_objects': all_objects})
def question_view(request, user_id):
my_question = UserAsking.objects.get(pk=user_id)
comment_form = CommentForm
#x = request.user.userprofile.userasking_set
if request.method == 'GET':
comment_form = comment_form(request.GET)
if comment_form.is_valid():
comments = comment_form.save(commit=False)
comments.comment = comment_form.cleaned_data['comment']
# you have to edit on userasking instance
#comments = Comment.objects.create(userasking=request.user.userprofile.userasking_set, comment=comments)
comments.save()
#return render(request, 'community/question_view.html', {'x': x})
return render(request, 'community/question_view.html', {'my_question': my_question,
'comment': comment_form})
community/forms.py
from django import forms
from .models import UserAsking, Comment
class UserAskingForm(forms.ModelForm):
title = forms.CharField(required=True,
widget=forms.TextInput(attrs={'placeholder': 'Type Your Title...',
'class': 'form-control',
'data-placement': 'top',
'title': 'type your title',
'data-tooltip': 'tooltip'
}),
help_text='Be specific and imagine you’re asking a question to another person')
question = forms.CharField(required=True,
widget=forms.Textarea(attrs={'placeholder': 'Type Your Details Of Your Question...',
'class': 'form-control',
'data-placement': 'top',
'title': 'type your question simply',
'data-tooltip': 'tooltip'
}),
help_text='Include all the information someone would need to answer your question')
class Meta:
model = UserAsking
fields = '__all__'
exclude = ['userprofile']
class CommentForm(forms.ModelForm):
comment = forms.CharField(max_length=500, required=False, widget=forms.Textarea(attrs={'placeholder': 'Type your comment simply',
'class': 'form-control'}))
class Meta:
model = Comment
fields = ['comment']
community/question_view.html
{% extends 'base.html' %}
{% block title %} This Question Belong To User: {{ request.user }} {% endblock %}
{% block body %}
<!-- Full Question View -->
<div class="my_question">
<div class="container">
<div class="answer-question">
<div class="row">
<div class="col-md-6 col-xs-12">
<div class="title">
<h3 class="text-primary">{{ my_question.title }}</h3>
<span class="clock">1 hour ago</span>
</div>
<div class="question">
<p class="">{{ my_question.question }}</p>
</div>
<div class="field">
<span>{{ my_question.field }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Options e.g 'Edit, Comment, Delete etc...' -->
<div class="options">
<div class="container">
<div class="col-sm-12">
<a data-showin=".my-form" class="showin">Comment</a> |
Edit |
Delete
<span>
Like |
Unlike
</span>
</div>
<hr>
<!-- Comment Text -->
<div class="user-answer">
<div class="row">
<div class="col-xs-12">
{% for field in comment %}
<p>(medo) - sub comment</p>
<p>1 hour ago</p>
{% endfor %}
</div>
</div>
</div>
<!-- Comment Field -->
{% include 'community/comment_form.html' %}
{{ x }}
</div>
</div>
{% endblock %}
community/comment_form.html
<form method="get" action="" class="hide my-form">
{% csrf_token %}
<div class="row">
{% for field in comment %}
<div class="col-sm-10">
<div class="form-group">
{{ field }}
</div>
</div>
<div class="col-sm-1">
<button type="submit" class="btn btn-primary btn-lg">Add Comment</button>
</div>
{% endfor %}
</div>
</form>
community/urls.py
from . import views
from django.urls import path
app_name = 'community'
urlpatterns = [
path('', views.user_questions, name='user_questions'),
path('ask-question/', views.user_asking, name='user_asking'),
path('ask-question/question-view/<int:user_id>/', views.question_view, name='question_view'),
]

how to change vote into voted after user votes the choices?

This Code is working perfectly. The only thing I want to change is submit button "Vote" into "Voted" after user voted the option ,instead of displaying error message " You Already Voted".So that the user can know which options he voted already when he logs in to vote the option next time
urls.py
path('<slug>/',views.options,name='options'),
path('<slug>/vote/', views.vote, name='vote'),
models.py
class Category(models.Model):
name = models.CharField(max_length=250)
slug = AutoSlugField(populate_from='name')
details = models.TextField(blank=True)
image = models.ImageField(blank=True,upload_to='categories')
views = models.IntegerField(default=0)
created = models.DateTimeField(auto_now=True)
modified = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=True)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "Categories"
class Option(models.Model):
name = models.CharField(max_length=250)
slug = AutoSlugField(populate_from='name')
image = models.ImageField(blank=True,upload_to='options')
details = models.TextField()
category = models.ForeignKey(Category, on_delete=CASCADE)
votes = models.IntegerField(default=0)
active = models.BooleanField(default=True)
def __str__(self):
return self.name
class Vote(models.Model):
option = models.ForeignKey(Option, on_delete=CASCADE)
voter = models.ForeignKey(User, on_delete=CASCADE)
slug = AutoSlugField(populate_from='option')
def __str__(self):
return self.voter
views.py
def options(request,slug):
category = Category.objects.get(slug=slug)
category.views += 1
category.save()
options = category.option_set.all().order_by('-votes')
if request.method == "POST":
if request.user.is_authenticated:
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.category = category
comment.user = request.user
comment.save()
messages.success(request, 'Comment Posted.')
else:
messages.error(request, 'You have to login first to give comment')
return redirect('rank:login')
else:
form = CommentForm()
return render(request, 'rank/options.html', {'options': options,'form':form,'title': 'options','category':category})
def vote(request,slug):
if request.user.is_authenticated:
option = Option.objects.get(slug=slug)
category = option.category
if Vote.objects.filter(slug=slug,voter_id=request.user.id).exists():
messages.error(request,'You Already Voted!')
return redirect('rank:options', category.slug)
else:
option.votes += 1
option.save()
voter = Vote(voter=request.user,option=option)
voter.save()
messages.success(request,'Voted.{} peoples also agree with you.'.format(option.votes-1))
return redirect('rank:options',category.slug)
else:
messages.error(request,"You have to login first to vote.")
return redirect('rank:login')
options.html
<ol type="1">
<center>{% bootstrap_messages %}</center>
{% for option in options %}
<div class="col-lg-6 col-md-6 mb-6">
<div class="card h-100">
<div class="card-body">
<b><li>
<img src="/media/{{option.image}}" width="400" height="300">
<h4>{{option.name}}
</h4>
<h5 class="card-text">{{ option.details}}</h5>
<h5>{{ option.votes }} votes</h5>
<form action="{% url 'rank:vote' option.slug %}" method="post">
{% csrf_token %}
<input type="submit" class="btn btn-success" value="Vote" >
</form>
</li></b>
</div>
<div class="card-footer">
<small class="text-muted"></small>
</div>
</div>
</div>
{% empty %}
<div class="card w-100">
<div class="card-body">
<h4>Item not available</h4>
</div>
</div>
{% endfor %}
</ol>
The simplest way to achieve this might be to add an attribute to each option to indicate whether the currently logged in user has voted on that option before you pass the options to the template.
For example:
def options(request,slug):
category = Category.objects.get(slug=slug)
category.views += 1
category.save()
options = category.option_set.all().order_by('-votes')
# Indicate whether the user has voted or not
for option in options:
option.has_voted = option.vote_set.filter(voter=request.user).exists()
...
return render(request, 'rank/options.html', {'options': options,'form':form,'title': 'options','category':category})
And then you can check the has_voted attribute in the template when you render the button:
{% if option.has_voted %}
You already voted
{% else %}
<input type="submit" class="btn btn-success" value="Vote" >
{% endif %}

Django: Mark as Read "Notifications"

I'm working on a school project. Right now any user can ask a question.
In order to notify all the users when any users asks a question I've created a new app & notifying them through the simple 'view' whenever a question is asked. But it's just plain notifications yet.
How can I mark them read once a user opens the Notification tab? Just like on social networks!
I suggest you to use ContentType to make a dynamic notifications fo any models. This snippet below is an example how to implement the notification system;
1. in your models.py
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from django.utils.translation import ugettext_lazy as _
class ContentTypeToGetModel(object):
"""
requires fields:
- content_type: FK(ContentType)
- object_id: PositiveIntegerField()
"""
def get_related_object(self):
"""
return the related object of content_type.
eg: <Question: Holisticly grow synergistic best practices>
"""
# This should return an error: MultipleObjectsReturned
# return self.content_type.get_object_for_this_type()
# So, i handle it with this one:
model_class = self.content_type.model_class()
return model_class.objects.get(id=self.object_id)
#property
def _model_name(self):
"""
return lowercase of model name.
eg: `question`, `answer`
"""
return self.get_related_object()._meta.model_name
class Notification(models.Model, ContentTypeToGetModel):
# sender = models.ForeignKey(
# User, related_name='notification_sender')
receiver = models.ForeignKey(
User, related_name='notification_receiver')
content_type = models.ForeignKey(
ContentType, related_name='notifications', on_delete=models.CASCADE)
object_id = models.PositiveIntegerField(_('Object id'))
content_object = GenericForeignKey('content_type', 'object_id')
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
STATUS_CHOICES = (
('reply', _('a reply')),
('comment', _('a comment')),
('message', _('a message'))
)
status = models.CharField(
_('Status'), max_length=20,
choices=STATUS_CHOICES, default='comment')
is_read = models.BooleanField(
_('Is read?'), default=False)
def __str__(self):
title = _('%(receiver)s have a %(status)s in the %(model)s:%(id)s')
return title % {'receiver': self.receiver.username, 'status': self.status,
'model': self._model_name, 'id': self.object_id}
class Meta:
verbose_name_plural = _('notifications')
ordering = ['-created']
2. in your views.py
from django.views.generic import (ListView, DetailView)
from yourapp.models import Notification
class NotificationListView(ListView):
model = Notification
context_object_name = 'notifications'
paginate_by = 10
template_name = 'yourapp/notifications.html'
def get_queryset(self):
notifications = self.model.objects.filter(receiver=self.request.user)
# mark as reads if `user` is visit on this page.
notifications.update(is_read=True)
return notifications
3. in your yourapp/notifications.html
{% extends "base.html" %}
{% for notif in notifications %}
{{ notif }}
{# for specific is like below #}
{# `specific_model_name` eg: `comment`, `message`, `post` #}
{% if notif._model_name == 'specific_model_name' %}
{# do_stuff #}
{% endif %}
{% endfor %}
So, when I creat that notifications?
eg: when the other user send a comment to receiver on this post.
from django.contrib.contenttypes.models import ContentType
def send_a_comment(request):
if request.method == 'POST':
form = SendCommentForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
#instance.sender = request.user
...
instance.save()
receiver = User.objects.filter(email=instance.email).first()
content_type = ContentType.objects.get(model='comment')
notif = Notification.objects.create(
receiver=receiver,
#sender=request.user,
content_type=content_type,
object_id=instance.id,
status='comment'
)
notif.save()
How about menu? Like this stackoverflow, facebook, instagram, or else?
you can handle it with templatetags, eg:
# yourapp/templatetags/notification_tags.py
from django import template
from yourapp.models import Notification
register = template.Library()
#register.filter
def has_unread_notif(user):
notifications = Notification.objects.filter(receiver=user, is_read=False)
if notifications.exists():
return True
return False
and the navs.html menu:
{% load notification_tags %}
{% if request.user.is_authenticated %}
<ul class="authenticated-menu">
<li>
<a href="/notifications/">
{% if request.user|has_unread_notif %}
<i class="globe red active icon"></i>
{% else %}
<i class="globe icon"></i>
{% endif %}
</a>
</li>
</ul>
{% endif %}
First you need ManyToManyField for user module who is readed a post.
profile.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
subscribed = models.ManyToManyField(User, related_name='subscribed', blank=True)
readed = models.ManyToManyField("blogs.BlogPost", related_name='readed', blank=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.user.username)
class Meta:
ordering = ("-created",)
If you have a blog model like this:
class BlogPost(models.Model):
author = models.ForeignKey(Profile, on_delete=models.CASCADE)
post_title = models.CharField("Post Title", max_length=150, unique=True)
post_content = models.TextField("Content")
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.post_title
class Meta:
ordering = ("-created",)
You need to create a button function in blog posts view.
def mark_as_read_button(request):
if request.method == "POST":
my_profile = Profile.objects.get(user=request.user)
post = request.POST.get("post_pk")
obj = BlogPost.objects.get(pk=post)
if obj in my_profile.readed.all():
my_profile.readed.remove(obj)
else:
my_profile.readed.add(obj)
return redirect(request.META.get("HTTP_REFERER"))
return redirect("blogs:subscribed-blogs")
Then you can use is in the template file like this:
{% extends 'base.html' %}
{% block title %}Subscribed Blog Posts{% endblock %}
{% block content %}
{% for post in posts %}
<h5 class="card-title">{{ post.post_title }}</h5>
{% if post in readed %}
<form action="{% url "blogs:mark_as_read" %}" method="POST">
{% csrf_token %}
<input type="hidden" name="post_pk" value={{ post.pk }}>
<button type="submit" class="btn btn-danger btn-sm">Mark as unread</button>
</form>
{% else %}
<form action="{% url "blogs:mark_as_read" %}" method="POST">
{% csrf_token %}
<input type="hidden" name="post_pk" value={{ post.pk }}>
<button type="submit" class="btn btn-success btn-sm">Mark as read</button>
</form>
{% endif %}
<p class="card-text">{{ post.created }}</p>
<p class="card-body">{{ post.post_content }}</p>
<hr>
{% endfor %}
{% endblock %}
Good coding.

Categories