Reputation: 1604
I have implemented Django notification in my index view. But I have more view like create a view, update view delete view etc. When the user first login to my application, I show the number of notification and links but when the user switches to another view then number of notification changes to zero. Is there any way to retain all the notification in every view of Django. This is my views.py file
from django.shortcuts import render, redirect, render_to_response
from django.http import HttpResponse, HttpResponseRedirect
from django.views.generic.edit import FormMixin
from .models import Report_item, ClaimForm, UserNotification
from django.views import generic
from django.db.models import Q
from django.contrib.auth import login, authenticate
from django.shortcuts import render, redirect
from django.utils import timezone
from django.views.generic import View, UpdateView, DeleteView
from .forms import SignUpForm, LoginForm
from django.contrib.auth import logout
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.core.urlresolvers import reverse_lazy
from django.db.models import Q
def IndexView(request):
if request.user.is_anonymous:
print("Hello")
query_list = Report_item.objects.all()
query = request.GET.get('q')
if query:
query_list = query_list.filter(Q(title__icontains=query) |
Q(item_type__icontains=query) |
Q(city__icontains=query) |
Q(Description__icontains=query)).distinct()
context = {
"object_list": query_list,
}
return render(request, "feed/index.html", context)
else:
query_list = Report_item.objects.all()
query = request.GET.get('q')
if query:
query_list = query_list.filter(Q(title__icontains=query) |
Q(item_type__icontains=query) |
Q(city__icontains=query) |
Q(location__icontains=query) |
Q(Description__icontains=query)).distinct()
n = UserNotification.objects.filter(user=request.user, viewed=False)
context = {
"object_list": query_list,
'notification': n,
'count': n.count(),
}
return render(request, "feed/index.html", context)
class SearchCtaegoryView(generic.ListView):
template_name = "feed/index.html"
def get_queryset(self):
query_list = Report_item.objects.all()
slug = self.kwargs.get("slug")
if slug:
query_list = query_list.filter(Q(category__icontains=slug) | Q(category__iexact=slug))
return query_list
class ReportCreate(generic.CreateView):
model = Report_item
fields = ['title', 'item_type', 'location', 'city', 'image', 'Description']
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.owner = self.request.user
self.object.save()
return FormMixin.form_valid(self, form)
class ReportDetail(generic.DetailView):
model = Report_item
template_name = 'feed/detail.html'
class ClaimForm(generic.CreateView):
model = ClaimForm
fields = ['Your_name', 'Your_mobile_number', 'Detail_proof']
class SignUpForm(generic.CreateView):
form_class = SignUpForm
template_name = "feed/SignUp.html"
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
print("form valid")
user = form.save(commit=False)
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
user.set_password(password)
form.save()
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('feed:index')
else:
print(form.errors)
return render(request, self.template_name, {'form': form})
class LoginForm(generic.CreateView):
print("login")
form_class = LoginForm
template_name = "feed/SignUp.html"
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
UserModel = get_user_model()
email = request.POST['email']
password = request.POST['password']
username = UserModel.objects.get(email=email)
user = authenticate(request, username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('')
else:
print(form.errors)
def logout_view(request):
logout(request)
query_list = Report_item.objects.all()
return render(request, "feed/index.html", {'object_list': query_list})
def Profile(request, username):
print(username)
qs = Report_item.objects.filter(owner__username=username)
context = {
"object_list": qs,
}
return render(request, "feed/profile.html", context)
class ReportUpdate(UpdateView):
model = Report_item
fields = ['title', 'item_type', 'location', 'city', 'image', 'Description']
class ReportDelete(DeleteView):
model = Report_item
success_url = reverse_lazy('feed:index')
class RequestItem(generic.CreateView):
model = UserNotification
fields = ['Name', 'Mobile_No', 'Proof']
def form_valid(self, form):
print(self.kwargs)
self.object = form.save(commit=False)
qs = Report_item.objects.filter(id=self.kwargs.get("pk"))
self.object.user = qs[0].owner
self.object.save()
return HttpResponse("<h1>Hello Friends </h1>")
def show_notification(request, notification_id):
n = UserNotification.objects.get(id=notification_id)
context = {
"n": n,
}
n.viewed = True
n.save()
return render(request, "feed/notification.html", context)
def read_notification(request, notification_id):
n = UserNotification.objects.get(id=notification_id)
n.viewed = True
n.save()
return HttpResponse("<h1>Hello Friends chai pee lo</h1>")
def mynotification(request):
n = UserNotification.objects.filter(user=request.user, viewed=False)
print(type(n))
return render_to_response("feed/loggedin.html",
{'full_name': request.user.first_name, 'notification': n, })
def read_Notification(request):
n = UserNotification.objects.filter(user=request.user)
print(type(n))
return render_to_response("feed/loggedin.html",
{'full_name': request.user.first_name, 'notification': n, })
Upvotes: 0
Views: 2052
Reputation: 5877
Fancy web sites use websockets/AJAX for this. But if you just want it to update on every page load, use a Django context processor.
A context processor is a function that runs every time any template is rendered.. and it doesn't matter which view is being accessed. The context processor can add additional template variables that are available in every template.
So, first write the function.. this function returns a dictionary containing object_list
, notification
, and count
for the current user if they are logged in, or nothing if they are not.
def notification_context(request):
# Most of the code below is simply copied from the question, it
# would be different for different applications. The important thing
# is that we have to figure out the values to be placed in the template
# context.
# If the user is not logged in, we don't know who they are so we return an empty.
# dictionary which results in nothing new being added to the template context.
if request.user.is_anonymous:
return {}
# look up the notifications for the current user
query_list = Report_item.objects.all()
query = request.GET.get('q', None)
if query:
query_list = query_list.filter(
Q(title__icontains=query) |
Q(item_type__icontains=query) |
Q(city__icontains=query) |
Q(location__icontains=query) |
Q(Description__icontains=query)
).distinct()
n = UserNotification.objects.filter(user=request.user, viewed=False)
# The return value must be a dict, and any values in that dict
# are added to the template context for all templates.
# You might want to use more unique names here, to avoid having these
# variables clash with variables added by a view. For example, `count` could easily
# be used elsewhere.
return {
'object_list': query_list,
'notification': n,
'count': n.count(),
}
Now tell django to use this processor. In your settings.py, find the TEMPLATES
section, and under OPTIONS
, you'll see context_processors
. Add yours, eg:
TEMPLATES = [{
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
# fill in the correct appname. Also, normally context processor functions go in
# context_processors.py, but if you only have one then it doesn't matter much.
'your_appname.views.notification_context',
],
},
},]
And that's it! Now, when the user is logged in, you should get your variables in the template every time. And if you want your heading to be in every template with these variables displayed, you should place the heading in a master site template and then all your other templates should extend that one. That way, you don't duplicate your heading template code 100 times...
PS: I'll add one more suggestion. Rather than directly returning your variables, nest them to avoid cluttering up your template namespace. Like so:
return { 'notifications': {
'object_list': query_list,
'notification': n,
'count': n.count(),
}
}
Then, in your template, it will look like this:
{{ notifications.count }}
{{ notifications.query_list }}
Etc etc.. much nicer.
Upvotes: 5