How to create a clean url for user profile in django - django

I am building an application . One of the functionalities of this application is to display objects created by users to other users when they login .Lets call these objects created by users (x).
Each of these objects displays the name of the user who created it . Bellow is my code of my view to display all objects created by users.
def CreatedObjects(request):
objects=Model-Class-Name.objects.all()
# to display all users .
users=User.objects.all()
template_name="blabla.html"
context={"objects":objects,"users":users}
return render(request,template_name,context)
my html file
<div class="objects>
<!--Display all available objects created by users-->
{% for obj in objects %}
<!--Display the name of the user who created object, with a link that will take you to user profile of this user -->
<div class="user'>
{% for user in users %}
<a href="{% url 'app_namespace:url_name' user.pk %}">{{obj.user.username}}
</div>
{% endfor %}
{% endfor %}
<div>
The userprofile link works ,but since i am using a for loop to loop through available users in the database ,the user name is displayed repeatedly . So my problem is how to avoid this .How can i create a userprfile link without for looping or how can i avoid the user name not to be displayed continuously on a single object .

Related

How to change the elements of navbar of User Change Page in Django Admin with Custom User model?

Below is the picture of a User Change Page of Django Admin in which the navbar of the page is marked with red color.
The name of the app under which the Custom User Model is defined is : Users
And the name of the Custom User model is : Custom User
So the question is how to change all 4 elements (i.e. Home,Users,Custom users,custom user) of the navbar of the User Change Page of Django admin??
So as we can see there are total 4 elements in the navbar of the User Change page of Django Admin :
1.Home
2.Users
3.Custom users
4.custom user
We will change all of these one by one, but first add few lines in the admin.py file of the Users app (The app under which the the custom user model is defined),which are as follows :
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import CustomUser
class CustomUserAdmin(UserAdmin):
change_form_template = 'change_form.html'
admin.site.register(CustomUser, CustomUserAdmin)
Explanation for the above code : First, we have imported important classes among which UserAdmin is imported so that it can be used as the base class to define the class CustomUserAdmin.Then we have defined the class CustomUserAdmin.Later we have registered the class CustomUserAdmin to the admin home page.
After this create a folder under the Users app (The app under which the the custom user model is defined) by name : templates
Now under the templates folder create a html file by name : change_form.html
In the change_form.html file paste the following code :
{% extends "admin/change_form.html" %}
{% load i18n admin_urls static admin_modify %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<!-- Element 1 -->
{% trans 'Home' %}
<!-- Element 1 ends -->
<!-- Element 2 -->
› {{ opts.app_config.verbose_name }}
<!-- Element 2 ends -->
<!-- Element 3 -->
› {% if has_view_permission %}
<a href="{% url opts|admin_urlname:'changelist' %}">
{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}
{% endif %}
<!-- Element 3 ends -->
<!-- Element 4 -->
›
{% blocktrans with name=opts.verbose_name %}
{{ name }}
{% endblocktrans %}
<!-- Element 4 ends -->
</div>
{% endblock %}
So there are 4 sections in the above code and also we have 4 elements in the navbar of the User Change Page.So one section for one element.
Changing 1st element (i.e. Home)
For this, you have to go to the section <!-- Element 1 --> of the file change_form.html in the templates folder of the Users app (The app under which the the custom user model is defined).
After that replace the string 'Home' with the name you want to give to the 1st element of the navbar of the User Change Page .
That's all for this element.
Changing 2nd element (i.e. Users)
For this you have to go to the apps.py file in Users app (The app under which the the custom user model is defined)
And then in the class which would be named like :
UsersConfig (i.e. App_NameConfig)
add following line :
verbose_name = 'Type here the name you want to give to the 2nd element of the navbar of User Change Page'
Note: Make sure you have added the above line in the class only by putting proper space before adding the above line.
That's all for this element.
Changing 3rd element (i.e. Custom users)
For this you have to go to the models.py file in Users app (The app under which the the custom user model is defined)
And there in the Custom User Model class you have to add the following code :
class Meta:
verbose_name="Type here the name you want to give to the 3rd element of the navbar of User Change Page"
Note: Make sure you have added the above lines in the class only by putting proper space before adding the above lines.
That's all for this element.
Changing 4th element (i.e. custom user)
For this, you have to go to the section <!-- Element 4 --> of the file change_form.html in the templates folder of the Users app (The app under which the the custom user model is defined).
And there replace {{ name }} with the name you want to give to the 4th element of the navbar of the User Change Page.
Also if you want to display the name of the user whose details is to be change then you can use :
{{ original|truncatewords:"18" }} in place of {{ name }}.
That's all for this element.
So in this way you can change all the 4 elements of the navbar of the User Change Page of Django Admin with Custom User Model.
I hope it will help you!!

Django get data from two tables, related data only

Okay so I have a homepage that displays images. This is accessed from my images tables. It contains a column of the owner, in the form of a user id. I also have a table of users, who've submitted those images. How do I make it so that when displaying images, it uses the ID to get the username from the user table?
views.py:
def index(request):
context = {}
populateContext(request, context)
context.update(gallery=ImageDoc.objects.only('thumbfile').order_by('-id'))
return render(request, 'register/index.html', context)
So in the index.html page, I can iterate through 'gallery' to show the images. Like so:
{% for image in gallery %}
<a href="/logo/{{ image.slug }}">
<img src="{{ MEDIA_URL }}{{ image.largethumbfile }}">
{{ image.title }} by {{ image.username }} for {{ image.price }}
</a>
{% endfor %}
"image.username" obviously doesn't work. I know I need to access the users table with this:
get_users = User.objects.get()
And reformat grabbing the images data to this:
get_images = ImageDoc.objects.get()
But I don't know the next step to ensure the data matches. Any ideas? Thank you!
If the Images table has the Users table as a foreign key, then each Images object will have a user_id parameter. Therefore, if you have a value called given_user_id you can do something like:
Images.objects.get(user_id=given_user_id)
If you have a username instead of a user_id, you can do something like:
Images.objects.get(user=User.objects.get(username=username))
Unfortunately, you cannot perform queries inside of a template block. You'll need to do any querying before you pass in your context object to the render function.

Showing the logged-in user inside base.html (django)

Is there a way to access the logged in user's firstname inside the base.html file?
I'm trying to do this, because i want to display who is currently logged in on the navigation bar, but it won't access the user's information, nor will it correctly check if the user is authenticated.
html inside base.html
Hi there,
{% if user.is_authenticated %}
{{user.first_name}}
{% else %}
Stranger
{% endif %}
request.user gives you the user object that is currently logged in. So you have full access to all the attributes and methods the User class has. To get the first_name, you can do {{ request.user.first_name }}. To get the full name you use {{ request.user.get_full_name }}.
If you use [RequestContext][1], by default you get user instance in your templates so you can use it as for its attributes as {{user.first_name}} and others. The user will be same a currently authenticated user which is also available in request.user in the views.
The RequestContext by default adds some default template contexts defined in TEMPLATE_CONTEXT_PROCESSORS in your settings.py.
In your view, you can use it as
#your view code
....
#send response by rendering the template and use Requestcontext while rendering template
return render_to_response('polls/detail.html', {'poll': p},
context_instance=RequestContext(request))
Reference - Django Tutorial 04

Dynamically create and save image with Django and PIL/Django-Photologue

I want to generate a page of html with dynamic content and then save the result as an image as well as display the page to the user. So, user signs up to attend conference and gives their name and org. That data is combined with html/css elements to show what their id badge for the conference will look like (their name and org on top of our conference logo background) for preview. Upon approval, the page is saved on the server to an image format (PNG, PDF or JPG) to be printed onto a physical badge by an admin later. I am using Django and django-photologue powered by PIL.
The view might look like this
# app/views.py
def badgepreview(request, attendee_id):
u = User.objects.get(id=attendee_id)
name = u.name
org = u.org
return render_to_response('app/badgepreview.html',
{'name':name,'org':org,},
context_instance = RequestContext(request),
)
The template could look like this
{# templates/app/badgepreview.html #}
{% extends "base.html" %}
{% block page_body %}
<div style='background:url(/site_media/img/logo_bg.png) no-repeat;'>
<h4>{{ name }}</h4>
<h4>{{ org }}</h4>
</div>
{% endblock %}
simple, but how do I save the result? Or is there a better way to get this done?
The only thing I can think is to do it in two passes:
a) Use http://www.xhtml2pdf.com/ to convert the HTML into a PDF.
b) Use something like http://www.swftools.org/gfx_tutorial.html to convert the PDF into an image.
I can't imagine that doing this would be fast...
You might be better off just converting and allowing them to download a PDF (i.e. use just step a) above) or trying to generate the badge directly without the HTML intermediate step.

Get user group in a template

I want to display a menu that changes according to the user group of the currently logged in user, with this logic being inside of my view, and then set a variable to check in the template to determine which menu items to show....I'd asked this question before, but my logic was being done in the template. So now I want it in my view...The menu looks as below
<ul class="sidemenu">
<li>General List </li>
<li>Sales List </li>
<li>Add a New Record </li>
<li>Edit Existing Record </li>
<li>Filter Records </li>
<li>Logout </li>
</ul>
Suppossing the user is management, they'll see everything...But assuming the user is in the group sales, they'll only see the first two and the last two items...and so on. I also want a dynamic redirect after login based on the user's group. Any ideas?
The standard Django way of checking permissions is by the individual permission flags rather than testing for the group name.
If you must check group names, being aware that Users to Groups is a many-to-many relationship, you can get the first group in the list of groups in your template with something like this:
{{ user.groups.all.0 }}
or using it like this in a conditional (untested but should work):
{% ifequal user.groups.all.0 'Sales' %}
...
{% endif %}
If you go with the preferred permission model you would do something like the following.
...
{% if perms.vehicle.can_add_vehicle %}
<li>Add a New Record </li>
{% endif %}
{% if perms.vehicle.can_change_vehicle %}
<li>Edit Existing Record </li>
{% endif %}
...
These are the permissions automatically created for you by syncdb assuming your app is called vehicle and the model is called Vehicle.
If the user is a superuser they automatically have all permissions.
If the user is in a Sales group they won't have those vehicle permissions (unless you've added those to the group of course).
If the user is in a Management group they can have those permissions, but you need to add them to the group in the Django admin site.
For your other question, redirect on login based on user group: Users to Groups is a many-to-many relationship so it's not really a good idea to use it like a one-to-many.
user.groups.all.0.name == "groupname"
Create a user_tags.py in your app/templatetags follow above:
# -*- coding:utf-8 -*-
from __future__ import unicode_literals
# Stdlib imports
# Core Django imports
from django import template
# Third-party app imports
# Realative imports of the 'app-name' package
register = template.Library()
#register.filter('has_group')
def has_group(user, group_name):
"""
Verifica se este usuário pertence a um grupo
"""
groups = user.groups.all().values_list('name', flat=True)
return True if group_name in groups else False
And finally in template use it:
{% if request.user|has_group:"Administradores"%}
<div> Admins can see everything </div>
{% endif %}
If you are working with Custom User Model (best practice with Django), you can create a method:
CustomUser(AbstractUser):
# Your user stuff
def is_manager(self):
return self.groups.filter(name='Management').exists()
Then inside your template you just call it this way:
{% if user.is_manager %}
{# Do your thing #}
{% endif %}
That method will be also useful validating permission in other parts of your code (views, etc.)