Django: logic not well applied in template using permissions (perm - django

I develop a Django app
I have specifics permission on 2 differents models
I use these permissions to display or not some link in a navbar
but I have an unexpected behavior I do not understand
below the html code with Django logic
code between should not be display with one of my user that do not have the two permissions
I control to be sure permissions are effectively False but even without permissions, links 'Randomize a patient' and 'Reallocate a patient' are displayed
what is wrong in my logic?
I give at the end, the entire navbar html code
partial template :
{% if user.is_authenticated %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{% trans 'Randomization' %}</a>
<div id="randomize" class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
{% if user_allowed_to_randomize and user_can_randomize or allowed_to_randomize and can_randomize %}
**<!-- SHOULD NOT BE DISPLAY - START-->**
{% if perms.randomization.can_randomize %}
<a class="dropdown-item" href="{% url 'randomization:randomisation_edit' %}">{% trans 'Randomize a patient' %}</a>
{% endif %}
{% if perms.randomization.can_reallocate %}
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{% url 'randomization:reallocate_edit' %}">{% trans 'Reallocate a treatment' %}</a>
{% endif %}
**<!-- SHOULD NOT BE DISPLAY - END-->**
{% endif %}
</div>
</li>
<li class="nav-item">
<a class="nav-link" href="#">{% trans 'Pharmacy' %}</a>
</li>
{% endif %}
complete template :
{% load static %}
{% load i18n %}
<nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-4">
<div class="container">
<a class="navbar-brand" href="">Intense TBM</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li>
</li>
<li class="nav-item active">
<a class="nav-link" href="{% url 'home' %}">{% trans 'Home' %}<span class="sr-only">(current)</span></a>
</li>
{% if user.is_authenticated %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{% trans 'Randomization' %}</a>
<!--Vérification stock via requete ajax stock avant d'afficher les menus deroulants-->
<div id="randomize" class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
<!--affichage par défaut pour les profils utilisateurs 'Site'-->
<!--OU SI DROIT ATTRIBUE APRES SELECTION LISTE SITE-->
{% if user_allowed_to_randomize and user_can_randomize or allowed_to_randomize and can_randomize %}
{% if perms.randomization.can_randomize %}
<a class="dropdown-item" href="{% url 'randomization:randomisation_edit' %}">{% trans 'Randomize a patient' %}</a>
{% endif %}
{% if perms.randomization.can_reallocate %}
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{% url 'randomization:reallocate_edit' %}">{% trans 'Reallocate a treatment' %}</a>
{% endif %}
{% endif %}
</div>
</li>
<li class="nav-item">
<a class="nav-link" href="#">{% trans 'Pharmacy' %}</a>
</li>
{% endif %}
<li class="nav-item">
<a class="nav-link" href="#">{% trans 'Contact' %}</a>
</li>
</ul>
{% if user.is_authenticated %}
<ul class="navbar-nav">
<!--Vérification stock via requete ajax stock avant d'afficher le message d'alerte-->
<li class="nav-item" id="alerte">
<!--affichage par défaut pour les profils utilisateurs 'Site'-->
{% if user_allowed_to_randomize and not user_can_randomize or allowed_to_randomize and not can_randomize %}
<a class="nav-link" id="informations" href="#" style="color:red; padding-right: 50px;"><strong>{% trans 'Insufficient stock' %}</strong></a>
{% endif %}
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ user.username }}
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
<!--Sélection d'un site-->
<form id="site_selectionne" method="POST" class="post-form">
{% csrf_token %}
<div class="form-group">
<!--data-randomization-url utilisé pour passer l'url dans le fichier .js qui ne considère pas les tag dajgo-->
<!--data-randomization-url récupéré pour définir l'url de la requete ajax-->
<select name="site" class="form-control" id="site" data-randomization-url="{% url 'randomization:stock' %}">
<option></option>
{% for site in sites %}
<!--récupération du site sélectionné middleware/context_processor-->
{% if site.sit_abr == site_selectionne %}
<option value="{{ site.sit_ide }}" selected>{{ site.sit_nom }} - {{ site.reg.pay.pay_nom }}</option>
{% else %}
<option value='{{ site.sit_ide }}'>{{ site.sit_nom }} - {{ site.reg.pay.pay_nom }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</form>
<!---->
<a class="dropdown-item" href="{% url 'password_change' %}">{% trans 'Change password' %}</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{%url 'logout'%}">{% trans 'Logout' %}</a>
</div>
</li>
</ul>
{% else %}
<form class="form-inline my-2 my-lg-0">
{% trans 'Login' %}
</form>
{% endif %}
</div>
</div>
</nav>

Related

django pagination with search not working

MultiValueDictKeyError at /search/
'search'
Request Method: GET
Request URL: http://127.0.0.1:8000/search/?page=2
Django Version: 4.1.5
Exception Type: MultiValueDictKeyError
Exception Value:
'search'
Exception Location: C:\Python311\Lib\site-packages\django\utils\datastructures.py, line 86, in getitem
Raised during: blogs.views.search
Python Executable: C:\Python311\python.exe
Python Version: 3.11.0
views.py
def search(request):
search = request.POST["search"]
blog_search = Blog.objects.filter(Q(title__icontains=search) | Q(description__icontains=search))
paginator = Paginator(blog_search, 5)
page_number = request.GET.get('page')
blogs = paginator.get_page(page_number)
return render(request,"frontend/searchblogs.html",{"blogs":blogs})
<div class="container">
<nav class="navbar navbar-light bg-light justify-content-end">
<form class="form-inline" method="post" action="{%url 'search' %}">
{% csrf_token %}
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" name="search" id="search" >
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</nav>
<h4 class="mt-4"></h4>
{% for blog in blogs %}
<div class="card mb-3" >
<div class="row no-gutters">
<div class="col-md-4">
<img src="{{blog.cover_img.url}}" alt="..." class="bd-placeholder-img card-img-top img-fluid">
</div>
<div class="col-md-8">
<div class="card-body">
<h4 class="card-title text-truncate">{{blog.title}}</h4>
<p class="card-text text-truncate">{{blog.description}}</p>
<div class="d-flex justify-content-between align-items-center">
<p class="text-muted">{{blog.date.date}}</p>
<p class="text-muted"><i class="fa fa-eye pl-2"></i> {{blog.view}}</p>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-end">
{% if blogs.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ blogs.previous_page_number }}">Previous</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1" aria-disabled="True">Previous</a>
</li>
{% endif %}
{% if blogs.number|add:'-4' > 1 %}
<li class="page-item"><a class="page-link" href="?page={{ blogs.number|add:'-5' }}">…</a></li>
{% endif %}
{% for i in blogs.paginator.page_range %}
{% if blogs.number == i %}
<li class="page-item active" aria-current="page">
<span class="page-link">
{{ i }}
<span class="sr-only">(current)</span>
</span>
</li>
{% elif i > blogs.number|add:'-5' and i < blogs.number|add:'5' %}
<li class="page-item"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if blogs.paginator.num_pages > blogs.number|add:'4' %}
<li class="page-item"><a class="page-link" href="?page={{ blogs.number|add:'5' }}">…</a></li>
{% endif %}
{% if blogs.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ blogs.next_page_number }}">Next</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1" aria-disabled="True">Next</a>
</li>
{% endif %}
</ul>
</nav>
</div>
Use:
views.py
def search(request):
search = request.GET["search"]
...
You're passing a GET request through the server (the ?page part of the URL), so you'll have to retrieve the data using request.GET['name']. You should also change your form method to GET. For a search, there isn't a good reason to use POST.
<div class="container">
<nav class="navbar navbar-light bg-light justify-content-end">
<form class="form-inline" method="GET" action="{%url 'search' %}">
{% csrf_token %}
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" name="search" id="search" >
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</nav>
...
</div>
Here's the documentation: https://docs.djangoproject.com/en/4.1/ref/request-response/#querydict-objects
Form methods: https://www.w3schools.com/tags/ref_httpmethods.asp
If you must use the POST method, refer to this question: Paginating the results of a Django forms POST request

Using django-filter generic view and paginate_by, how to build the pagination urls?

First time using django-filter, so I might be using it wrong.
I'm basically trying to mimic Django Admin filtering, using a generic FilterView, setting filterser_class and adding paginate_by
filters.py
class ProductFilter(django_filters.FilterSet):
name = django_filters.CharFilter(lookup_expr='icontains', label='Filter by Title')
categories = django_filters.AllValuesFilter(
field_name='categories__name',
label="Filter by Category",
widget=django_filters.widgets.LinkWidget(attrs={'class': 'list-menu'}),
)
brand = django_filters.AllValuesFilter(
field_name='brand__short_name',
label="Filter by Brand",
widget=django_filters.widgets.LinkWidget(attrs={'class': 'list-menu'}),
)
class Meta:
model = Product
fields = ['categories', 'brand', 'name']
views.py
class ProductFilterView(FilterView):
filterset_class = ProductFilter
paginate_by = 20
product_filter.html
<section class="section-content padding-y">
<div class="container">
<div class="row">
<aside class="col-md-3">
<div class="card">
<form method="get">
{% csrf_token %}
{% for field in filter.form.visible_fields %}
<article class="filter-group">
<header class="card-header">
<a href="#" data-toggle="collapse" data-target="#collapse_1" aria-expanded="true" class="">
<i class="icon-control fa fa-chevron-down"></i>
<h6 class="title">{{ field.label_tag }}</h6>
</a>
</header>
<div class="filter-content collapse show" id="collapse_1">
<div class="card-body">
{{ field }}
</div> <!-- card-body.// -->
</div>
</article> <!-- filter-group .// -->
{% endfor %}
<input type="submit" class="btn btn-block btn-primary" value="Filter"/>
</form>
</div> <!-- card.// -->
</aside> <!-- col.// -->
<main class="col-md-9">
<header class="border-bottom mb-4 pb-3">
<div class="form-inline">
<span class="mr-md-auto">{{ filter.qs | length }} products found </span>
</div>
</header><!-- sect-heading -->
<div class="row">
{% for obj in page_obj %}
<div class="col-md-4">
<figure class="card card-product-grid">
<div class="img-wrap">
<img src="/media/{{ obj.productimage_set.first.image|default:'products/missing.png' }}">
</div> <!-- img-wrap.// -->
<figcaption class="info-wrap">
<div class="fix-height">
{{ obj.name }}
<div class="price-wrap mt-2">
<span class="price">$ {{ obj.price }}</span>
<!--<del class="price-old">$1980</del>-->
</div>
</div>
Add to cart
</figcaption>
</figure>
</div> <!-- col.// -->
{% endfor %}
</div> <!-- row end.// -->
<nav class="mt-4" aria-label="Page navigation">
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item"><a class="page-link" href="?page=1">First</a></li>
<li class="page-item"><a class="page-link" href="?page={{ page_obj.previous_page_number }}">Previous</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">First</a></li>
<li class="page-item disabled"><a class="page-link" href="#">Previous</a></li>
{% endif %}
{% for page in page_obj.paginator.page_range %}
{% ifequal page page_obj.number %}
<li class="page-item active"><a class="page-link">{{ page }}</a></li>
{% else %}
<li class="page-item"><a class="page-link" href="?page={{ page }}">{{ page }}</a></li>
{% endifequal %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item"><a class="page-link" href="?page={{ page_obj.next_page_number }}">Next</a></li>
<li class="page-item"><a class="page-link" href="?page={{ page_obj.paginator.num_pages }}">Last</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">Next</a></li>
<li class="page-item disabled"><a class="page-link" href="#">Last</a></li>
{% endif %}
</ul>
</nav>
</main> <!-- col.// -->
</div>
</div> <!-- container .// -->
</section>
It almost works as intended.
But those pagination urls will reset any filtering.
I'm considering using {{ request.GET.param1 }} to rebuild all the filters, but it doesn't feel like the right way to solve this.
I've tried a solution using context processors, as described by José L. Patiño here:
How to paginate Django with other get variables?
But it leads to another problem: it's possible to reapply filtering after advancing some pages, and it results in invalid pages.
Any suggestions?

Django - Pagination

I'm working on To-Do App.
I have two kinds of data,
Upcoming To-do Item and
Completed To-do Items.
So, I'm filtering data in views.py as upcoming items and completed items. I want to display them on the same page using pagination. I'm getting result too but if upcoming item completed in page-1 I was unable to visit page-2 because upcoming item for page-2 was empty, but I have items on completed items. I couldn't see that.
views.py
#login_required(login_url='login')
def home(request):
todo_form = TodoForm()
current = timezone.now()
todo_items_upcoming = Todo.objects.filter(user_id=request.user, completed=False).order_by('-date_created')
todo_items_completed = Todo.objects.filter(user_id=request.user, completed=True)
pagi1 = Paginator(todo_items_upcoming, 4)
pagi2 = Paginator(todo_items_completed, 4)
page_num = request.GET.get('page')
page_num2 = request.GET.get('page')
page_obj = pagi1.get_page(page_num)
page_obj2 = pagi2.get_page(page_num2)
if request.method == "POST":
todo_form = TodoForm(request.POST)
if todo_form.is_valid():
data = todo_form.cleaned_data.get('title')
obj = Todo.objects.create(date_created=current, title=data, user_id=request.user)
context = {'todo_form':todo_form, 'page_obj':page_obj, 'page_obj2':page_obj2}
return render(request, 'todo/main.html', context)
main.html
{% extends 'todo/index.html' %}
{% load crispy_forms_tags %}
{% block content %}
<nav aria-label="...">
<ul class="pagination justify-content-center">
<!-- pagination - previous pages -->
{% if page_obj.has_previous or page_obj2.has_previous %}
<li class="page-item">
{% if page_obj.has_previous %}
<a class="page-link" href="?page={{ page_obj.previous_page_number }}" tabindex="-1">«</a>
{% else %}
<a class="page-link" href="?page={{ page_obj2.previous_page_number }}" tabindex="-1">«</a>
{% endif %}
</li>
{% endif %}
<!-- pagination - current page -->
<li class="page-item active">
<a class="page-link" href="?page={{ page_obj.number }}">{{ page_obj.number }}</a>
</li>
<!-- pagination - Next pages -->
{% if page_obj.has_next or page_obj2.has_next %}
<li class="page-item">
{% if page_obj.has_next %}
<a class="page-link" href="?page={{ page_obj.next_page_number }}">»</a>
{% else %}
<a class="page-link" href="?page={{ page_obj2.next_page_number }}">»</a>
{% endif %}
</li>
{% endif %}
</ul>
</nav>
<div class="center-column">
<h2 class="heading" style="text-align: center;">Hello {{ request.user.username }}, Here's your ToDo List</h2>
<form action="" method="POST" id='form-create'>
{% csrf_token %}
<div style="text-align: center;">
{{ todo_form.title }}
<button type="submit" class="form-control btn btn-primary mb-3 mr-sm-2">Add Items</button>
</div>
</form>
<h4 class="heading" style="text-align: center;">Upcoming ToDo Items</h4><br>
<div class="row">
<div class="col" id="upcomItem">
<ul class="list-group" id="upcomingItems">
{% for i in page_obj %}
<li class="list-group-item list-group-item-primary mb-2" id="upcomingItem">{{ i.title }}
<div class="float-right">
<button type="submit" class="btn-sm btn-danger ml-2 mt-2 mr-2 mb-1">Delete</button>
</div>
<div class="float-right">
<button type="submit" class="btn-sm btn-success ml-2 mt-2 mr-2 mb-1" id="update_btn">Update</button>
</div>
<div class="float-right">
<button type="submit" class="btn-sm btn-dark ml-2 mt-2 mr-2 mb-1" id="completed_btn">Completed</button>
</div>
</li>
{% endfor %}
</ul>
</div>
</div>
<hr style="border-top: 1px solid #999; ">
<div class="row">
<div class="col">
<h4 class="heading" style="text-align: center;">Completed ToDo Items</h4>
<ul class="list-group" id='compItems'>
{% for i in page_obj2 %}<hr>
<li class="list-group-item list-group-item-primary mb-2" id="upcomingItem">{{ i.title }}
<div class="float-right">
<button type="submit" class="btn-sm btn-danger ml-2 mt-2 mr-2 mb-1">Delete</button>
</div>
<div class="float-right">
<button type="submit" class="btn-sm btn-success ml-2 mt-2 mr-2 mb-1" >Update</button>
</div>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endblock %}
At first I have used or in template tags in if condition I got this error. Error Message occurs when I try to add new to-do item
I tried and operator in template tags I didn;'t even get page-2 link eventhough I have upcoming items and no extra completed items.
Use or operator as #Willem pointed. And you active link href must be {{ page_obj.number }} instead {{ page_obj.page_number }}:
<li class="page-item active">
<a class="page-link" href="?page={{ page_obj.number }}">{{ page_obj.number }}</a>
</li>
As you can see your error EmptyPage raised in your template at line 18
Your conditions should be a disjunction of the conditions of the paginators, so or instead of and:
{% if page_obj.has_previous or page_obj2.has_previous %}
…
{% endif %}
the same for .has_next. The previous and next page then should be handled by checking which page object has a next page, so:
{% if page_obj.has_next or page_obj2.has_next %}
<li class="page-item">
{% if page_obj.has_next %}
<a class="page-link" href="?page={{ page_obj.next_page_number }}">»</a>
{% else %}
<a class="page-link" href="?page={{ page_obj2.next_page_number }}">»</a>
{% endif %}
</li>
{% endif %}
That being said, I'm not sure this provides the best user experience. Perhaps it is better to make two separate paginations (so work with ?pagedone=…&pagetodo=…).

How to insert the blog pagination on Django Blog

I trying to implement pagination on my blog using the Bootstrap.
I did comment because in this way is working but shows only one number.
I did try some different way but not working yet, I feel that is close. or not. :-)
Following my "blog.html" file.
Thank you.
<nav aria-label="Page navigation example">
<ul class="pagination pagination-lg justify-content-center">
{% if queryset.has_previous %}
<li class="page-item">
<a class="page-link" href="?{{ page_request_var }}={{ queryset.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% endif%}
{% comment %} <li class="page-item"><a class="page-link" href="?{{ page_request_var }}">{{ queryset.previous_page_number}}</a></li> {% endcomment %}
<li class="page-item"><a class="page-link" href="?{{ page_request_var }}">{{ queryset.number }}</a></li>
{% comment %} <li class="page-item"><a class="page-link" href="?{{ page_request_var }}">{{ queryset.next_page_number}}</a></li> {% endcomment %}
{% if queryset.has_next %}
<li class="page-item">
<a class="page-link" href="?{{ page_request_var }}={{ queryset.next_page_number }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% endif%}
</ul>
</nav>
Add pagination in the html file like this:
<ul class="pagination justify-content-center">
{% if is_paginated %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-dark mb-4" href="?page=1">First</a>
<a class="btn btn-outline-dark mb-4" href="?page={{ page_obj.previous_page_number }}">Previous</a>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-dark mb-4" href="?page={{ num }}">{{ num }}</a>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<a class="btn btn-outline-dark mb-4" href="?page={{ num }}">{{ num }}</a>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<a class="btn btn-outline-dark mb-4" href="?page={{ page_obj.next_page_number }}">Next</a>
<a class="btn btn-outline-dark mb-4" href="?page={{ page_obj.paginator.num_pages }}">Last</a>
{% endif %}
{% endif %}
</ul>
I'm supposing you did two things.First you used Paginator in your views.py and also your queryset is not empty. Following code is completely functional and targets your template only:
paginator.html
<div class="pagination-container justify-content-center">
<ul class="pagination pagination-primary">
{% if paginator.has_previous %}
<li class="page-item arrow-margin-left">
<a class="page-link" href="?page={{ paginator.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true"><i class="fa fa-angle-double-left" aria-hidden="true"></i></span>
</a>
</li>
{% else %}
<li class="page-item arrow-margin-left">
<a class="page-link" href="#" aria-label="Previous">
<span aria-hidden="true"><i class="fa fa-angle-double-left" aria-hidden="true"></i></span>
</a>
</li>
{% endif %}
{% for i in paginator.paginator.page_range %}
{% if paginator.number == i %}
<li class="page-item active">
<a class="page-link">{{ i }}</a>
</li>
{% else %}
<li class="page-item">
<a class="page-link" href="?page={{ i }}">
{{ i }}
</a>
</li>
{% endif %}
{% endfor %}
{% if paginator.has_next %}
<li class="page-item arrow-margin-right">
<a class="page-link" href="?page={{ paginator.next_page_number }}" aria-label="Next">
<span aria-hidden="true">
<i class="fa fa-angle-double-right" aria-hidden="true"></i>
</span>
</a>
</li>
{% else %}
<li class="page-item arrow-margin-right">
<a class="page-link" href="#" aria-label="Next">
<span aria-hidden="true">
<i class="fa fa-angle-double-right" aria-hidden="true"></i>
</span>
</a>
</li>
{% endif %}
</ul>
</div>
Now you can call this code wherever you need it, for example :
articles.html
<div class="pagination-container justify-content-center col-md-6">
{% include 'pages/page_articles_paginator.html' with paginator=page_articles%}
</div>
this will assign page_articles to

Py 3.6 // Django 2.1.4 : Accessing User Profile mysteriously changes the status of user.is_authenticated to True

I have been having this problem for 2 weeks now I can't seem to solve it.
I have a social website where user's can upload their resumes for recruiters to see.
And when I access some user's profile, the Navbar acts as if I am logged in, which I am not.
I tried fixing this issue by using get_queryset() ,it worked but I couldn't manage to display user's profile data.
so I stuck with get().
Here's a visual explanation:
As you can see the navbar says Home/Login/Signin
Now if I access John Doe's Profile, the navbar will switch to Home/Profile/Logout:
Here's my code;
views.py:
class HomeProfile(ListView):
"Di splays all active users in db"
template_name = 'profile/home_profile.html'
queryset = MyModel.objects.filter(is_active=True)
class Get_Profile(DetailView):
"fetches user's profile"
def get(self, request, pk):
user = MyModel.objects.get(pk=pk)
return render(request, 'profile/profile.html', {'user':user})
urls.py
urlpatterns = [
path('homepage/profiles/', user_view.HomeProfile.as_view(), name='homepage'),
path('homepage/profile/<int:pk>/', user_view.Get_Profile.as_view(), name='user-profile'),
]
base_test.html
<nav class="navbar navbar-expand-sm navbar-dark bg-dark sticky-top">
<a class="navbar-brand" href="{% url 'home' %}">Navbar</a>
<button class="navbar-toggler d-lg-none" type="button" data-toggle="collapse" data-target="#collapsibleNavId" aria-controls="collapsibleNavId"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsibleNavId">
<ul class="navbar-nav ml-auto mt-2 mt-lg-0">
<li class="nav-item active">
<a class="nav-link" href="{% url 'homepage' %}">Home<span class="sr-only">(current)</span></a>
</li>
{% if not user.is_authenticated %}
<li class="nav-item">
<a class="nav-link" href="{% url 'login' %}">Log In</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'signup' %}">Sign Up</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="#">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'logout' %}">Log Out</a>
</li>
{% endif %}
</ul>
</div>
</nav>
home_profile.html
<!-- this is the home template that displays all active users -->
{% extends 'base_test.html' %}
{% block title %} My Site | Profiles {% endblock title %}
{% block content %}
<div class="card-columns text-center padding">
{% for user in mymodel_list %}
<div class="card">
<img class="rounded-circle" src="{{user.profile.image.url}}" width=150 height=150>
<div class="card-body">
<h5 class="card-title">Full name : {{user.get_full_name}}</h5>
<p class="crad-text">Occupation/job : {{user.profile.occupation}}</p>
<a type="button" href="{% url 'user-profile' user.pk %}" style="color:whitesmoke;" class="btn btn-primary btn-sm">Profile</a>
</div>
</div>
{% endfor %}
</div>
{% endblock content %}
{% block footer %}
{% endblock footer %}
profile.html
<!-- user profile template -->
{% extends 'base_test.html' %}
{% load custom_tags %}
{% block title %} My Site | {{user.get_full_name}} {% endblock title %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-lg-8 order-lg-2 padding">
<div class="tab-content">
<div class="tab-pane active" id="profile">
<div class="row">
<div class="col-lg-12">
<h6><strong>About</strong></h6>
<p>
{{user.profile.bio}}
</p>
<hr>
</div>
<div class="col-lg-12">
<h6><strong>Skills</strong></h6>
{% for skill in user.profile.skills|split:',' %}
<span class="badge badge-primary">{{skill}}</span>
{% endfor %}
<hr>
<h6><strong>Hobbies</strong></h6>
<p>
{% for hobbie in user.profile.hobbies|split:',' %}
<span class="badge badge-success">{{hobbie}}</span>
{% endfor %}
</p>
<hr>
</div>
<!-- removes the social part -->
</div>
</div>
</div>
</div>
<div class="col-lg-4 order-lg-1 padding">
<h1 class="mb-3 text-center">{{user.get_full_name}}</h1>
<hr>
<img src="{{user.profile.image.url}}" class="mx-auto img-fluid rounded-circle d-block" alt="avatar" width=150><br>
<div class="text-center">
<h4>{{user.profile.school}}</h4>
<p><strong>Hometown :</strong> {{ user.profile.hometown}}</p>
<p><strong>Current City:</strong> {{user.profile.location}}<p>
<p><strong>Occupation/Job:</strong> {{user.profile.occupation}}<p><br>
<hr>
<button type="button" class="btn btn-outline-success btn-md">View CV</button>
</div>
</div>
</div>
</div>
{% endblock content %}
{% block footer %}
{% endblock footer %}
I don't know What is causing this strange behaviour!!
Actually, you are mixing up with request.user and your user object for resume. You should change the context variable name from user to something else. for example:
class Get_Profile(DetailView):
"fetches user's profile"
def get(self, request, pk):
user = MyModel.objects.get(pk=pk)
return render(request, 'profile/profile.html', {'profile':user}) # <-- Here
You've used the same variable name, user, for the user whose profile you are viewing as for the one who is actually using the site. You need to pick another name.
(Also, unrelated, but you don't need to - and shouldn't - define the get method in your detail view.)