Creating user profile pages in Django - django

I'm a beginner in Django. I need to setup a website, where each user has a profile page. I've seen django admin. The profile page for users, should store some information which can be edited by the user only. Can anyone point me out how that is possible?. Any tutorial links would be really helpful. Also, are there any modules for django, which can be used for setting up user page.

You would just need to create a view that's available to an authenticated user and return a profile editing form if they're creating a GET request or update the user's profile data if they're creating a POST request.
Most of the work is already done for you because there are generic views for editing models, such as the UpdateView. What you need to expand that with is checking for authenticated users and providing it with the object that you want to provide editing for. That's the view component in the MTV triad that provides the behavior for editing a user's profile--the Profile model will define the user profile and the template will provide the presentation discretely.
So here's some behavior to throw at you as a simple solution:
from django.contrib.auth.decorators import login_required
from django.views.generic.detail import SingleObjectMixin
from django.views.generic import UpdateView
from django.utils.decorators import method_decorator
from myapp.models import Profile
class ProfileObjectMixin(SingleObjectMixin):
"""
Provides views with the current user's profile.
"""
model = Profile
def get_object(self):
"""Return's the current users profile."""
try:
return self.request.user.get_profile()
except Profile.DoesNotExist:
raise NotImplemented(
"What if the user doesn't have an associated profile?")
#method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
"""Ensures that only authenticated users can access the view."""
klass = ProfileObjectMixin
return super(klass, self).dispatch(request, *args, **kwargs)
class ProfileUpdateView(ProfileObjectMixin, UpdateView):
"""
A view that displays a form for editing a user's profile.
Uses a form dynamically created for the `Profile` model and
the default model's update template.
"""
pass # That's All Folks!

You can
create another Model for storing profile information about user
add AUTH_PROFILE_MODULE='yourprofileapp.ProfileModel' to settings.py
In profile editing view, allow only logged in users to edit their own profiles
example:
#login_required
def edit_profile(request):
'''
edit profile of logged in user i.e request.user
'''
You can also make sure that whenever new user is created the user's profile is also created using django's signals
Read about storing additional information about users from django documentation

Related

how do I make sure a particular user is the one logged in?

so I have some code which creates a user but how do I make sure every url that the user goes to will be in his/her own user session such that request.user will be the user I created?
def liked(request):
try:
sp = Spotify(auth_manager=oauth)
liked = sp.current_user_saved_tracks(limit=30)['items']
spotify_user = sp.current_user()
user__ , created =
User.objects.get_or_create(username=spotify_user['uri'],
first_name=spotify_user["display_name"])
userprofile = UserProfile.objects.get_or_create(user=user__)[0]
i have other views i want only accessible to the user created or gotten from the get_or_create, i reckon I'd have to use the #login_required decorator but then again I do not know what constitutes this "login" with respect to the user I created. How do I do ensure that user is the logged in user?
Django's default MIDDLEWARE takes care of this for you.
In every request object or self.request there is a user object.
Django checks the session via the cookie that the browser sends with every request, and puts the user object in the current request.
An example in a Class based view:
class ExampleView(TemplateView):
template = 'example.html'
def get_context_data(self, **kwargs):
context = super(ExampleView, self).get_context_data(**kwargs)
user = self.request.user
users_data = ExampleData.objects.filter(user=user)
Once a user is logged in, every other page is put into the session. Just log that user in first.
If you want to check if the user is logged in
In class based views;
if self.request.user.is_authenticated
In function based view
if request.user.is_authenticated
Ok as i understand you need to limit some users to access some pages and not for others .. i suggest to use permissions way
add permission to any Model you Have Like this
then when you create your special user do this to assign this permission to him like that : myuser.user_permissions.add('can_view_all_clients', 'another_perm', ...)
For Function Based Views :
from django.contrib.auth.decorators import permission_required
#permission_required("YourModel.can_view_all_clients")
def your_special_view(request):
return 'your view'
For Class Based View :
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.views.generic import DetailView
class ModelDetailView(PermissionRequiredMixin, DetailView):
template_name = "model_detail.html"
model = Model
permission_required = "can_view_all_clients"

Handle various groups of users' profiles with django-userena

I have successfully implemented a way to create users belonging to different groups with userena using a different form for each signup url, inheriting the userena signup form and overriding the save method to include the user to a group or another.
For instance in my /brands/ urls I have:
url(r'^signup/$',
'userena.views.signup',
{'template_name': 'userena/signup_form_brands.html', 'signup_form': SignupFormBrands}
),
and in that form I have:
from userena.forms import SignupForm
from django.contrib.auth.models import Group
class SignupFormBrands(SignupForm):
def save(self):
# First save the parent form and get the user.
new_user = super(SignupFormBrands, self).save()
new_user.groups.add(Group.objects.get(name='Brands'))
return new_user
So I got what I needed with the batteries included in userena. But now I would like to keep using the included profile editing / viewing capabilities of userena but with 2 different kinds of profiles. I would like to create 2 different profile models, one for my default users and one for the brands. Then I want userena to be able to edit the right kind of profile model according to the user belonging to a group or another. I'm not sure how this works and how I could do it.
Edit: userena uses profile = user.get_profile()to edit the profile so I'm going to try to assign a different profile object by editing this class.
you can override User.get_profile by following code:
original_get_profile = User.get_profile
def get_profile(self):
if getattr(settings, 'AUTH_PROFILE_MODULE', None) != 'profiles.Profile':
return original_get_profile(self)
if not hasattr(self, '_profile_cache'):
self._profile_cache = self.profile
self.profile.user = self
return self._profile_cache
User.get_profile = get_profile
Put it somewhere in models.py file with your profiles.
code copied from here: http://pastebin.com/MP6bY8H9

Filter django admin by logged in user

I'm new to django.
I'm creating simple app in which I have users enter some data and view it later. I need to make django admin show to the user only the data she enter and non of the other users data.
Is it possible to change it to multiple admin pages?
Thank you
Store a reference to a user in your model.
models.py:
from django.db import models
from django.contrib.auth.models import User
class MyModel(models.Model):
user = models.ForeignKey(User)
... (your fields) ...
Force the current user to be stored in that field (when using admin)
Force any list of these objects to be (additionally) filtered by the current user (when using admin)
Prevent other users from editing (even though they can't see the object in the list they could access its change_form directly)
admin.py:
from django.contrib import admin
from models import MyModel
class FilterUserAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.user = request.user
obj.save()
def get_queryset(self, request):
# For Django < 1.6, override queryset instead of get_queryset
qs = super(FilterUserAdmin, self).get_queryset(request)
return qs.filter(created_by=request.user)
def has_change_permission(self, request, obj=None):
if not obj:
# the changelist itself
return True
return obj.user === request.user
class MyModelAdmin(FilterUserAdmin):
pass # (replace this with anything else you need)
admin.site.register(MyModel, MyModelAdmin)
If you have MyOtherModel with a foreign key "user" just subclass MyOtherModelAdmin from FilterUserAdmin in the same manner.
If you want certain superusers to be able to see anything, adjust queryset() and has_change_permission() accordingly with your own requirements (e.g. don't filter/forbid editing if request.user.username=='me').
In that case you should also adjust save_model() so that your editing doesn't set the user and thus "take away" the object from the previous user (e.g. only set user if self.user is None (a new instance)).
You'll have to save in the user to every item and query each item with that user as search criteria. You'll probably build a base model which all your other models will inherit from. To get you started take a look at row-level permissions in the admin.

Implementing a generic protected preview in Django

I'm trying to add some kind of generic preview functionality to the Django admin. Opposed to Django's builtin preview-on-site functionality this preview should only be visible to logged in users with specific permissions.
All my content models have the same base class which adds a status like published and unpublished. Obviously unpublished content doesn't appear on the website, but editors should still be able to preview an unpublished site.
I read about class based views in the upcoming Django 1.3 release which might be well suited to implement it in a generic way. With Django 1.2 i can't seem to come up with a solution without touching any single view and adding specific permission checks. Has anyone done something like that before?
I believe the Django Admin already provides a "show on site" option to the admin pages of any models which provides a get_absolute_url() method. Using decorators, it should be possible to do this in a generic way across models
class MyArticleModel(Article): #extends your abstract Article model
title = .....
slug = ......
body = ......
#models.permalink
def get_absolute_url(self): # this puts a 'view on site' link in the model admin page
return ('views.article_view', [self.slug])
#------ custom article decorator -------------------
from django.http import Http404
from django.shortcuts import get_object_or_404
def article(view, model, key='slug'):
""" Decorator that takes a model class and returns an instance
based on whether the model is viewable by the current user. """
def worker_function(request, **kwargs):
selector = {key:kwargs[key]}
instance = get_object_or_404(model, **selector)
del kwargs[key] #remove id/slug from view params
if instance.published or request.user.is_staff() or instance.author is request.user:
return view(request, article=instance, **kwargs)
else:
raise Http404
return worker_function
#------- urls -----------------
url(r'^article/(?(slug)[\w\-]{10-30})$', article_view, name='article-view'),
url(r'^article/print/(?(id)\d+)$',
article(view=generic.direct_to_template,
model=MyArticleModel, key='id'),
name='article-print-view'
)
#------ views ----------------
from django.shortcuts import render_to_response
#article(MyArticleModel)
def article(request, article):
#do processing!
return render_to_response('article_template.html', {'article':instance},
xontext_instance=RequestContext(request) )
Hope this is informative (and hopefully correct ;)

Profile page getting acess to user object in Django

I have a requirement where I have to register users first via email. So, I went with django-registraton and I managed to integrate tat module into my django project.
After a successful login, the page redirects to 'registration/profile.html'.
I need to get access to the user object which was used in the authentication.
I need this object to make changes to a model which holds custom profile information about my users. I have already defined this in my models.py
Here is the URL I am using to re-direct to my template..
url(r'^profile/$',direct_to_template,{'template':'registration/profile.html'}),
So my question is this... after login, the user has to be taken to a profile page that needs to be filled up.
Any thoughts on how I can achieve this?
I have set up something similar earlier. In my case I defined new users via the admin interface but the basic problem was the same. I needed to show certain page (ie. user settings) on first log in.
I ended up adding a flag (first_log_in, BooleanField) in the UserProfile model. I set up a check for it at the view function of my frontpage that handles the routing. Here's the crude idea.
views.py:
def get_user_profile(request):
# this creates user profile and attaches it to an user
# if one is not found already
try:
user_profile = request.user.get_profile()
except:
user_profile = UserProfile(user=request.user)
user_profile.save()
return user_profile
# route from your urls.py to this view function! rename if needed
def frontpage(request):
# just some auth stuff. it's probably nicer to handle this elsewhere
# (use decorator or some other solution :) )
if not request.user.is_authenticated():
return HttpResponseRedirect('/login/')
user_profile = get_user_profile(request)
if user_profile.first_log_in:
user_profile.first_log_in = False
user_profile.save()
return HttpResponseRedirect('/profile/')
return HttpResponseRedirect('/frontpage'')
models.py:
from django.db import models
class UserProfile(models.Model):
first_log_in = models.BooleanField(default=True, editable=False)
... # add the rest of your user settings here
It is important that you set AUTH_PROFILE_MODULE at your setting.py to point to the model. Ie.
AUTH_PROFILE_MODULE = 'your_app.UserProfile'
should work.
Take a look at this article for further reference about UserProfile. I hope that helps. :)