Django context processor being called twice per request - python

I've found only one topic like this and not a single answer in there seems to work.
I have two context processors:
def cart_view(request):
try:
cart_id = request.session['cart_id']
cart = Cart.objects.get(id=cart_id)
request.session['total'] = cart.items.count()
print('OLD CART USED')
except:
cart = Cart()
cart.save()
cart_id = cart.id
request.session['cart_id'] = cart_id
cart = Cart.objects.get(id=cart_id)
print('NEW CART CREATED')
return {'cart':cart}
# dropdown menu categories to every page
def categories(request):
print('CATEGORIES CONTEXT PROCCESOR')
categories = Category.objects.all()
return {'dropdown_categories':categories}
Settings:
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.template.context_processors.media',
'shopping.views.cart_view',
'shopping.views.categories',
]
Via those print statements I'm able to see that each one of those CP being executed twice per request, although I'm rendering just base.html. What may be the problem?
import traceback; traceback.print_stack() gives this two times:
P.S. I know that I'm querying the DB every time I use CP, I'll add caching later.
Cosole log(that's one page load):
OLD CART USED
CATEGORIES CONTEXT PROCCESOR
[30/Aug/2018 18:56:13] "GET / HTTP/1.1" 200 2651
OLD CART USED
CATEGORIES CONTEXT PROCCESOR
[30/Aug/2018 18:56:13] "GET / HTTP/1.1" 200 2651
View:
class HomePageView(TemplateView):
template_name = 'base.html'
Project URLs:
urlpatterns = [re_path(r'^',include('shopping.urls',namespace='shop'))]
App's URLs:
urlpatterns = [re_path(r'^$',views.HomePageView.as_view(),name='home')]

Well, I don't what magic is this but the issue of getting two requests per page load had something to do with this line of code in my base.html:
<img src="#" width="30" height="30" class="d-inline-block align-top" alt="">
As soon as I deleted it, everything started to work normaly...

Related

How to order URLs in Django? I am getting `Page Not Found` error because of misplaced urls?

I am getting below error when I want to add a project or go to project_create URL.
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/project/add/
Raised by: projects.views.project_detail_view
the URL says /project/add/ that according to the view it must open project_create_view but the error is raised by detail view projects.views.project_detail_view.
This is the URL:
path('project/<slug:project_slug>/delete/',
project_delete_view, name='project_delete'),
path('project/<slug:project_slug>/update/',
project_update_view, name='project_update'),
path('project/<slug:project_slug>/',
project_detail_view, name='project_detail'),
path('projects/list/', all_projects_view, name='all_projects'),
path('project/add/', project_create_view, name='project_create'),
path('administration/', administration, name='administration'),
path("", home, name='home'),
if I comment this line path('project/<slug:project_slug>/',project_detail_view, name='project_detail'), then project_create URL goes to right view and right template. Why is this happening? I used different name, url and view name. Why is this happening?
Edit: I added both views
#login_required
def project_create_view(request):
if not request.user.is_superuser:
raise PermissionDenied
if request.method == 'POST':
form = ProjectForm(request.POST, request.FILES)
if form.is_valid():
title = form.instance.title
form.save()
project = get_object_or_404(Project, title=title)
messages.success(request, 'Project created successfully.')
return redirect(project.get_absolute_url())
form = ProjectForm()
return render(request, 'projects/project_create.html', {'form': form})
def project_detail_view(request, project_slug):
project = get_object_or_404(Project, slug=project_slug)
session_key = 'project_views{}'.format(project.slug)
if not request.session.get(session_key, False):
Project.objects.filter(id=project.pk).update(
visit_count=F('visit_count') + 1
)
request.session[session_key] = True
context = {
'project': project
}
return render(request, 'projects/project_detail.html', context)
Dynamic URLs must be on the bottom of the list,
urlpatterns = [
# Fixed URLs
path("", home, name='home'),
path('administration/', administration, name='administration'),
path('project/add/', project_create_view, name='project_create'),
path('projects/list/', all_projects_view, name='all_projects'),
# Dynamic URLs
path('project/<slug:project_slug>/',
project_detail_view, name='project_detail'),
path('project/<slug:project_slug>/delete/',
project_delete_view, name='project_delete'),
path('project/<slug:project_slug>/update/',
project_update_view, name='project_update'),
]
Ref: Django URL routing
You can order it by app, or by path, for example if you have more than one that starts with project you may group them in a different url pattern list.
projecturls =[
# your project path urls
]
urlpatterns =[
path('project/', include(projecturls)),
# ...
]

Django:Error upon having more than than 3 models in one view

am trying to create a dashboard template page having a summary of the system model.But when i exceed more than three models in the view,it shows up an error.How do i go about this?
def dashboard(request):
return render(request=request,
template_name = 'main/admin.html',
context = {
"teachers_list": Teacher.objects.all(),
"stream_list": Stream.objects.all(),
"fees_list":Fees.objects.all(),
"books_list":Book.objects.all()
}
)
I just realised the error is from one of the url template a tags

Django : go back to correct paginator page

I have simple blog app that is using paginator for listing articles.
I want to be able to add button in article detail page that will direct user to same page that this article is on.
I want to take slug from current url and send it to paginator so that it directs user to ?page=X where article is on.
I checked paginator docs and didn't find any info on how to retrieve page number of specific object.
my views:
def blog(request):
posts = Article.objects.all()
paginator = Paginator(posts, 3)
page = request.GET.get('page')
posts = paginator.get_page(page)
return render(request,'blog.html',{'posts':posts})
def article_id(request,slug):
articleid = Article.objects.get(slug=slug)
return render(request, 'blogid.html', {'article':articleid})
my urls:
urlpatterns = [
url(r'^$', views.blog, name = 'blog'),
url(r'^(?P<slug>[\w-]+)/$', views.article_id, name = 'article_id'),
]
You can get the position of the object via
position=Article.objects.filter(your_filter_key=your_filter_value).order_by('other_filter_order').count()
Then get the page number via
items_per_page=yout_items_per_page
page = int(position/items_per_page)
Solved with help of Giancarlo's answer.
I added below to article_id
def article_id(request,slug):
articleid = Article.objects.get(slug=slug)
position = Article.objects.filter(date__gt=articleid.date).count()
page = str(int((position)/3)+1)
return render(request, 'blogid.html', {'article':articleid, 'page':page})
And then in template link looks like /blog/?page={{page}}

Passing user auth status in view

I am using Django Cookiecutter as template. And by default in urls.py there is following url:
url(r'^about/$', TemplateView.as_view(template_name='pages/about.html'), name='about'),
and because i need to pass some additional parameters in it i wanted to use it as:
url(r'^about/$', index, name='about'),
Where index is from my views, but when i use the view, my system does not recognise that user is logged in, should i somehow pass user in my index too or what am i doing wrong?
What i am doing in my view:
def index(request):
return render_to_response('pages/about.html', {
'categories': Category.objects.all(),
'posts': Post.objects.all()[:5]
})
I solved it by using render instead of render to response so the method after change looks like this:
def index(request):
categories = Category.objects.all()
posts = Post.objects.all()[:5]
context = {'categories': categories, 'posts': posts}
return render(request, 'pages/home.html', context)

How to remove session variable in a template after it's job is done in django

I have a app called dashboard which is where I redirect all logged in users with an option to add articles by the user.
After the user hits Submit button in the form, the data is sent to /dashboard/article/save URL via POST and after the data is stored, the view returns HttpResponseRedirect to show_dashboard which renders dashboard.html with a session variable result.
In the dashboard template file, I have added a notify.js code to show acknowledgements to user. The problem is if this session var is defined, everytime the dashboard page is showed, the notification is triggered EVEN if the user didn't add an article.
(I'm new to using web frameworks so I do not know how this all works properly)
Some code:
dashboard/models.py:
class Article(models.Model):
id = models.IntegerField(primary_key=True)
ar_title = models.CharField(max_length=25)
ar_data = models.CharField(max_length=500)
user = models.ForeignKey(User,on_delete=models.CASCADE)
def getArticleTitle(self):
return self.title
def getArticleData(self):
return self.title
def getArticleAuthor(self):
return self.user
dashboard/urls.py:
urlpatterns = [
url(r'^$', views.show_dashboard,name='home_dashboard'),
url(r'^profile/save/', views.save_profile,name="save_profile"),
url(r'^newsfeed/', views.get_newsfeed,name="newsfeed",),
url(r'^profile/', views.show_profile,name="show_profile"),
url(r'^article/save/', views.add_new_article,name="add_new_article"),
]
dashboard/views.py:
#login_required
def show_dashboard(request):
return render(request,'dashboard/dashboard.html',{'form':NewArticleForm()})
def add_new_article(request):
if(request.method == 'POST'):
ar_title= request.POST['ar_title']
ar_data = request.POST['ar_data']
user = request.user
form = NewArticleForm(request.POST)
if(form.is_valid()):
Article.objects.create(ar_title=ar_title,ar_data=ar_data,user=user)
request.session["result"] = "add_article_OK"
return HttpResponseRedirect(reverse('home_dashboard'))
dashboard.html:
{% ifequal request.session.result 'add_article_OK' %}
<script>
$.notify("New article added successfully",
{position:"bottom right","className":"success","autoHide":"yes","autoHideDelay":"3000"});
</script>
{% endifequal %}
Now, how do I remove this session value after it has displayed the message? I know del request.session['result'] can be issued but where can I put it in this heirarchy of moves?
Do it in the show_dashboard view.
Instead of getting the value from the session in the template, pop it in the view and pass it to the template; that way you take care of getting and clearing it in one go.
#login_required
def show_dashboard(request):
context = {
'form': NewArticleForm(),
'result': request.session.pop('result', None)
}
return render(request,'dashboard/dashboard.html',context)
...
{% ifequal result 'add_article_OK' %}

Categories