2010-01-13 07:35:29 +08:00
from django . db import transaction
2008-12-25 14:17:42 +08:00
from django . conf import settings
from django . contrib import admin
from django . contrib . auth . forms import UserCreationForm , UserChangeForm , AdminPasswordChangeForm
2008-07-19 07:54:34 +08:00
from django . contrib . auth . models import User , Group
2009-12-10 00:57:23 +08:00
from django . contrib import messages
2008-07-19 07:54:34 +08:00
from django . core . exceptions import PermissionDenied
2008-12-25 14:17:42 +08:00
from django . http import HttpResponseRedirect , Http404
2011-04-23 02:17:16 +08:00
from django . shortcuts import get_object_or_404
from django . template . response import TemplateResponse
2008-08-10 17:43:48 +08:00
from django . utils . html import escape
2010-02-09 23:02:39 +08:00
from django . utils . decorators import method_decorator
2008-07-19 07:54:34 +08:00
from django . utils . translation import ugettext , ugettext_lazy as _
2010-01-13 07:35:29 +08:00
from django . views . decorators . csrf import csrf_protect
2011-06-09 06:18:46 +08:00
from django . views . decorators . debug import sensitive_post_parameters
2008-07-19 07:54:34 +08:00
2010-02-09 23:02:39 +08:00
csrf_protect_m = method_decorator ( csrf_protect )
2008-07-19 07:54:34 +08:00
class GroupAdmin ( admin . ModelAdmin ) :
search_fields = ( ' name ' , )
ordering = ( ' name ' , )
filter_horizontal = ( ' permissions ' , )
2011-08-15 17:01:12 +08:00
def formfield_for_manytomany ( self , db_field , request = None , * * kwargs ) :
if db_field . name == ' permissions ' :
qs = kwargs . get ( ' queryset ' , db_field . rel . to . objects )
# Avoid a major performance hit resolving permission names which
# triggers a content_type load:
kwargs [ ' queryset ' ] = qs . select_related ( ' content_type ' )
return super ( GroupAdmin , self ) . formfield_for_manytomany ( db_field , request = request , * * kwargs )
2008-07-19 07:54:34 +08:00
class UserAdmin ( admin . ModelAdmin ) :
2010-01-13 07:35:29 +08:00
add_form_template = ' admin/auth/user/add_form.html '
change_user_password_template = None
2008-07-19 07:54:34 +08:00
fieldsets = (
( None , { ' fields ' : ( ' username ' , ' password ' ) } ) ,
( _ ( ' Personal info ' ) , { ' fields ' : ( ' first_name ' , ' last_name ' , ' email ' ) } ) ,
2010-01-11 05:58:01 +08:00
( _ ( ' Permissions ' ) , { ' fields ' : ( ' is_active ' , ' is_staff ' , ' is_superuser ' , ' user_permissions ' ) } ) ,
2008-07-19 07:54:34 +08:00
( _ ( ' Important dates ' ) , { ' fields ' : ( ' last_login ' , ' date_joined ' ) } ) ,
( _ ( ' Groups ' ) , { ' fields ' : ( ' groups ' , ) } ) ,
)
2010-01-13 07:35:29 +08:00
add_fieldsets = (
( None , {
' classes ' : ( ' wide ' , ) ,
' fields ' : ( ' username ' , ' password1 ' , ' password2 ' ) }
) ,
)
2008-08-26 01:10:20 +08:00
form = UserChangeForm
2008-08-10 12:22:21 +08:00
add_form = UserCreationForm
2008-08-10 17:43:48 +08:00
change_password_form = AdminPasswordChangeForm
2008-07-19 07:54:34 +08:00
list_display = ( ' username ' , ' email ' , ' first_name ' , ' last_name ' , ' is_staff ' )
2009-04-02 00:43:01 +08:00
list_filter = ( ' is_staff ' , ' is_superuser ' , ' is_active ' )
2008-07-19 07:54:34 +08:00
search_fields = ( ' username ' , ' first_name ' , ' last_name ' , ' email ' )
ordering = ( ' username ' , )
filter_horizontal = ( ' user_permissions ' , )
2008-08-24 05:45:36 +08:00
2010-01-13 07:35:29 +08:00
def get_fieldsets ( self , request , obj = None ) :
if not obj :
return self . add_fieldsets
return super ( UserAdmin , self ) . get_fieldsets ( request , obj )
def get_form ( self , request , obj = None , * * kwargs ) :
"""
Use special form during user creation
"""
defaults = { }
2010-01-20 06:19:26 +08:00
if obj is None :
defaults . update ( {
' form ' : self . add_form ,
' fields ' : admin . util . flatten_fieldsets ( self . add_fieldsets ) ,
} )
2010-01-13 07:35:29 +08:00
defaults . update ( kwargs )
return super ( UserAdmin , self ) . get_form ( request , obj , * * defaults )
2009-01-15 04:22:25 +08:00
def get_urls ( self ) :
2011-09-12 06:36:16 +08:00
from django . conf . urls import patterns
2009-01-15 04:22:25 +08:00
return patterns ( ' ' ,
( r ' ^( \ d+)/password/$ ' , self . admin_site . admin_view ( self . user_change_password ) )
) + super ( UserAdmin , self ) . get_urls ( )
2008-08-24 05:45:36 +08:00
2011-06-09 06:18:46 +08:00
@sensitive_post_parameters ( )
2010-02-09 23:02:39 +08:00
@csrf_protect_m
2010-01-13 07:35:29 +08:00
@transaction.commit_on_success
def add_view ( self , request , form_url = ' ' , extra_context = None ) :
2008-12-25 14:04:11 +08:00
# It's an error for a user to have add permission but NOT change
# permission for users. If we allowed such users to add users, they
# could create superusers, which would mean they would essentially have
# the permission to change users. To avoid the problem entirely, we
# disallow users from adding users if they don't have change
# permission.
2008-07-19 07:54:34 +08:00
if not self . has_change_permission ( request ) :
2008-12-25 14:17:42 +08:00
if self . has_add_permission ( request ) and settings . DEBUG :
# Raise Http404 in debug mode so that the user gets a helpful
# error message.
raise Http404 ( ' Your user does not have the " Change user " permission. In order to add users, Django requires that your user account have both the " Add user " and " Change user " permissions set. ' )
2008-07-19 07:54:34 +08:00
raise PermissionDenied
2010-01-13 07:35:29 +08:00
if extra_context is None :
extra_context = { }
defaults = {
2008-07-19 07:54:34 +08:00
' auto_populated_fields ' : ( ) ,
2008-08-10 12:22:21 +08:00
' username_help_text ' : self . model . _meta . get_field ( ' username ' ) . help_text ,
2010-01-13 07:35:29 +08:00
}
extra_context . update ( defaults )
return super ( UserAdmin , self ) . add_view ( request , form_url , extra_context )
2008-08-24 05:45:36 +08:00
2011-06-09 06:18:46 +08:00
@sensitive_post_parameters ( )
2008-08-10 17:43:48 +08:00
def user_change_password ( self , request , id ) :
2009-04-19 05:04:40 +08:00
if not self . has_change_permission ( request ) :
2008-08-10 17:43:48 +08:00
raise PermissionDenied
user = get_object_or_404 ( self . model , pk = id )
if request . method == ' POST ' :
form = self . change_password_form ( user , request . POST )
if form . is_valid ( ) :
new_user = form . save ( )
msg = ugettext ( ' Password changed successfully. ' )
2009-12-10 00:57:23 +08:00
messages . success ( request , msg )
2008-08-10 17:43:48 +08:00
return HttpResponseRedirect ( ' .. ' )
else :
form = self . change_password_form ( user )
2010-01-13 07:35:29 +08:00
fieldsets = [ ( None , { ' fields ' : form . base_fields . keys ( ) } ) ]
adminForm = admin . helpers . AdminForm ( form , fieldsets , { } )
2011-04-23 02:17:16 +08:00
context = {
2008-08-10 17:43:48 +08:00
' title ' : _ ( ' Change password: %s ' ) % escape ( user . username ) ,
2010-01-13 07:35:29 +08:00
' adminForm ' : adminForm ,
2008-08-10 17:43:48 +08:00
' form ' : form ,
' is_popup ' : ' _popup ' in request . REQUEST ,
' add ' : True ,
' change ' : False ,
' has_delete_permission ' : False ,
' has_change_permission ' : True ,
' has_absolute_url ' : False ,
' opts ' : self . model . _meta ,
' original ' : user ,
' save_as ' : False ,
' show_save ' : True ,
2011-04-23 02:17:16 +08:00
}
return TemplateResponse ( request , [
self . change_user_password_template or
' admin/auth/user/change_password.html '
] , context , current_app = self . admin_site . name )
2008-08-10 17:43:48 +08:00
2010-11-20 06:45:51 +08:00
def response_add ( self , request , obj , post_url_continue = ' ../ %s / ' ) :
"""
Determines the HttpResponse for the add_view stage . It mostly defers to
its superclass implementation but is customized because the User model
has a slightly different workflow .
"""
2011-02-24 09:00:57 +08:00
# We should allow further modification of the user just added i.e. the
# 'Save' button should behave like the 'Save and continue editing'
# button except in two scenarios:
# * The user has pressed the 'Save and add another' button
# * We are adding a user in a popup
if ' _addanother ' not in request . POST and ' _popup ' not in request . POST :
2010-11-20 06:45:51 +08:00
request . POST [ ' _continue ' ] = 1
return super ( UserAdmin , self ) . response_add ( request , obj , post_url_continue )
2008-07-19 07:54:34 +08:00
admin . site . register ( Group , GroupAdmin )
admin . site . register ( User , UserAdmin )