Unable to retrieve user information from django templates - python

i want to use loged in user information in my base template
{% if request.user.username %}
Logout
{% else %}
Login
{% endif %}

from django.template import RequestContext
def top(request):
return render_to_response('top.html',{}, context_instance=RequestContext(request))

If you're just wanting to check if they're logged in to display the login or logout links, I would use is_authenticated instead
{% if user.is_authenticated %}
Logout
{% else %}
Login
{% endif %}
If you are wanting to use information from the user, you can use the variables in the user class {{ user.username }}
{% if user.is_authenticated %}
Hi, {{ user.first_name }}, Logout
{% else %}
Login
{% endif %}
I use code with this structure in my base.html and it works well. I don't have anything in the template_content_processor - it works in the template on its own.

Related

Django Validation Error raised but not displayed for shopping cart app

I am running Django 2.2 and have written a simple shopping cart. I wish to validate two fields at the same time in such a way that both cannot be empty at the same time. In my forms.py,
from django import forms
class CartAddProductForm(forms.Form):
cc_handle = forms.CharField(required=False, label='CC Handle', empty_value='')
lc_handle = forms.CharField(required=False, label='LC Handle', empty_value='')
def clean(self):
cleaned_data = super().clean()
if cleaned_data.get('cc_handle') == '' and cleaned_data.get('lc_handle') == '':
print("issue detected")
raise forms.ValidationError('Either cc or lc handle is required.')
return cleaned_data
This is following the official Django docs on cleaning and validating fields that depend on each other. The print() statement above lets me know that the issue has been detected, i.e. both fields are empty. Running the Django server, I see that the issue was indeed detected but no validation error message was displayed on top of the originating page. The originating page is the product page that contains the product and a link to add the product to the shopping cart. Normally the validation error message is displayed at the top of the page.
According to the docs, the validation is done when is_valid() is called. So I put a diagnostic print of my views.py
from django.shortcuts import render, redirect, get_object_or_404
from django.views.decorators.http import require_POST
from shop.models import Product
from .cart import Cart
from .forms import CartAddProductForm
#require_POST
def cart_add(request, product_id):
cart = Cart(request)
product = get_object_or_404(Product, id=product_id)
form = CartAddProductForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
cart.add(product=product,
cc_handle=cd['cc_handle'],
lc_handle=cd['lc_handle'])
else:
print('invalid form')
return redirect('cart:cart_detail')
And indeed the words 'invalid form' popped up. The code then takes me to the shopping cart. Instead, what I want is to be at the product page and show the validation error informing the reader that both fields cannot be empty. Is there a simple way of doing it?
For required=True fields in the forms, if I leave it blank, there will be a message popping up saying that I need to fill it in. So I want to do something similar except the validation requires that both fields cannot be empty.
This is different from this Stackoverflow answer because that is a registration form. You can redirect it to the same form whereas for this case, the CartAddProductForm is embedded in all the products page on the site. If possible, I want the validation to occur at the same stage as the field with required=True option.
The product/detail.html template looks like the following.
{% extends "shop/base.html" %}
{% load static %}
{% block title %}
{{ product.name }}
{% endblock %}
{% block content %}
<div class="product-detail">
<img src="{% if product.image %}{{ product.image.url }}{% else %}{% static "img/no_image.png" %}{% endif %}">
<h1>{{ product.name }}</h1>
<h2>{{ product.category }}</h2>
<p class="price">${{ product.price }}</p>
<form action="{% url "cart:cart_add" product.id %}" method="post">
{{ cart_product_form }}
{% csrf_token %}
<input type="submit" value="Add to cart">
</form>
{{ product.description|linebreaks }}
</div>
{% endblock %}
Adding this line in form template has cleared your issue.
{{ cart_product_form.non_field_errors }}
product/detail.html:
{% extends "shop/base.html" %}
{% load static %}
{% block title %}
{{ product.name }}
{% endblock %}
{% block content %}
<div class="product-detail">
<img src="{% if product.image %}{{ product.image.url }}{% else %}{% static "img/no_image.png" %}{% endif %}">
<h1>{{ product.name }}</h1>
<h2>{{ product.category }}</h2>
<p class="price">${{ product.price }}</p>
<form action="{% url "cart:cart_add" product.id %}" method="post">
{{ cart_product_form }}
{% csrf_token %}
{{ cart_product_form.non_field_errors }} // This line will raise validation errors
<input type="submit" value="Add to cart">
</form>
{{ product.description|linebreaks }}
</div>
{% endblock %}
Doc:(Copied from official documentation)
Note that any errors raised by your Form.clean() override will not be
associated with any field in particular. They go into a special
“field” (called all), which you can access via the
non_field_errors() method if you need to. If you want to attach errors
to a specific field in the form, you need to call add_error().
Your view is inconditionnally redirecting to cart_details so no surprise you don't see the validation errors - you'd have to render the invalid form for this. You should only redirect when the post succeeded.

Django checking for a query string

When someone clicks on my site's logout link, I want them to be redirected to the login page but I want a message to pop up saying that they were successfully logged out. However, I don't want this behaviour to occur when someone normally visits the login page.
I decided to pass in a query string so now when someone hits logout they are redirected to users/login/?logout. How can I check for this in my template though? I want to do something like:
{% if ______ %}
*Message box appears*
{% endif %}
Thanks!
Well, you can simply use the built-in Django messaging feature!
Here's a simple example:
# views.py
from django.contrib import messages
def register(request):
# Logic
# ...
messages.success(request, 'Registered successfully!')
# ...
# More logic
-
# example.html
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li class="{{ message.tags }}">
{{ message|safe }}
X
</li>
{% endfor %}
</ul>
{% endif %}
There's a more in-depth documentation available on Django's official docs website: https://docs.djangoproject.com/en/1.11/ref/contrib/messages/
Referring to this document, I believe what you are looking for is this
{% if not request.user.is_authenticated %}
<p>You are logged out!</p>
{% endif %}

Using Django Templates with User Authentication

I have a site which I am using user authentication to limit access to.
I am using django-allauth to handle social media authentication, but want to limit access to staff accounts only (set in the django admin panel).
I want to use a template as a header (bootstrap, nav bar etc.) with the main content loaded afterwards, or a message asking the user to login or request to be verified by admins.
My header template file: inventory/header.html
<body>
{% load bootstrap3 %}
{% if user.is_authenticated %}
{% if user.is_staff%}
{% block main %}{% endblock %}
{% block scripts %}{% endblock %}
{% else %}
<h1>Please ask an administrator to activate your account</h1>
{% endif %}
{% else %}
<h1>Please login to see this page</h1>
{% endif %}
</body>
And another template called by the view: inventory/home.html
{% include "inventory/header.html" %}
{% block main %}
This is the home page.
{% endblock %}
The view:
def home(request):
return render(request,'inventory/home.html')
Whenever I call the view, regardless of whether the user is logged in or a staff member, the main block is always displayed. The other error messages are displayed correctly.
I'm trying to avoid inserting is_authenticated/is_staff into all of my templates. I have also thought about using the login_required view decorator but that does not solve my is_staff issue.
Turns out I should have used
{% extends "inventory/header.html" %}
instead of
{% include "inventory/header.html" %}
Doh!

Django - How to give a URL a Variable

I am in the process of making a edit listing system for my website and have run into an issue, the problem I am having is with my edit listing portal which displays all the listings associated with the relevant account. The idea is that people can click on any of the listings and it will take them to the edit listing form, however my edit listing form is suppose to be given a public key when you click on it. My problem is I dont know how to put the listings pk into the url. Could somebody please advise me on what to do?
Thanks
Code -
Listings Portal -
{% extends "base.html" %}
{% block content %}
<h1 class="pageheader">Edit Your Job Listings</h1>
<div class="joblistings">
<p class="jobcounter">There are <b>{{ joblistings.count }}</b> jobs available</p>
{% if joblistings %}
{% for joblisting in joblistings %}
{% if joblisting.active_listing %}
<div class="listings-item">
<a href="{% url 'editlisting' %}"> <--- THIS IS THE URL
<ul>
<li class="listing-title">{{ joblisting.job_title }} - {{ joblisting.business_name }}</li>
<li>Region: {{ joblisting.business_address_suburb }}</li>
<li>Pay Rate: ${{ joblisting.pay_rate }}</li>
<li>Contact Method: {{ joblisting.contact_method }}</li>
</ul>
</a>
</div>
{% endif %}
{% endfor %}
{% else %}
<p>Unfortunately all of the job opportunities have been taken at this moment.</p>
{% endif %}
</div>
{% endblock %}
Edit Listing View -
# This is the view which manages the edit listing page
#login_required(redirect_field_name='login')
def editlisting(request, pk):
post = JobListing.objects.get(pk=pk)
#if str(request.user) != str(post.user):
# return redirect("index")
if request.method == "POST":
print("test")
form = JobListingForm(request.POST, instance=post, force_update=True)
if form.is_valid():
form.save()
return redirect('index')
else:
print("else")
form = JobListingForm(instance=post)
context = {
"form": form
}
return render(request, "editlisting.html", context)
How about this?
Click me

How to compare django object and string in templates

i want to know how to compare an object with a string in templates. Do in need to do it in views.py or in my html templates.
my views.py
permission = permission_group_sas.objects.all()
context_dict = {
'permission':permission,
# 'groups':groups,
}
return render_to_response(template, RequestContext(request, context_dict))
my html
{% for user in user.groups.all %}
{% for value in permission %}
<h4>1. {{ user.name }}
<p>2. {{ value.group }}</p></h4>
{% if value.group == user.name %}
OK!!
{% endif%}
{% endfor %}
{% endfor %}
value.group is an object and user.name is a string. So the word OK!! does not appear in my screen What is the correct way to do it. Thank you.

Categories

Resources