Работа со стандартной авторизацией в Django

Хотелось использовать стандартную авторизацию, но нужно было, естественно, её расширить.
Вот как это получилось.

Добавки в файлы:
Файл models.py

# стандартный пользователь Django
from django.contrib.auth.models import User
...
# расширяем модель пользователя
class UserProfile( models.Model ):
	user = models.ForeignKey( User, null = True )
	birthday = models.DateField( blank = True, null = True )
	weight = models.IntegerField( blank = True, null = True )
	height = models.IntegerField( blank = True, null = True )
	language = models.CharField( max_length = 2, choices = LANGUAGES, default = 'ru' )
	created_at = models.DateTimeField( auto_now_add = True )
	updated_at = models.DateTimeField( auto_now = True )
...
# автолинкование профиля пользователя к пользователю при его сохранении
def user_post_save(sender, instance, **kwargs):
    ( profile, new ) = UserProfile.objects.get_or_create(user=instance)

models.signals.post_save.connect(user_post_save, sender=User)

Файл urls.py

from main.views import ... signup, login, logout, my_profile, user_card
...
		  url( r'^accounts/signup/$', signup ),
		  url( r'^accounts/login/$', 'django.contrib.auth.views.login', { "template_name": "accounts/login.html" } ),
		  url( r'^accounts/logout/$', 'django.contrib.auth.views.logout_then_login' ),

Логин и логаут — стандартные, а регистрация — своя, т.к. есть дополнительные поля.

Файл views.py

from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout
...
class UserForm( forms.ModelForm ):
	username = forms.CharField( max_length = 30 )
	firstname = forms.CharField( max_length = 30, required = False )
	lastname = forms.CharField( max_length = 30, required = False )
	email = forms.CharField( max_length = 30 )
	pass1 = forms.CharField( widget = forms.PasswordInput, label = "Пароль", min_length = 6, max_length = 30 )
	pass2 = forms.CharField( widget = forms.PasswordInput, label = "Пароль ещё раз" )
	
	def clean_pass2( self ):
		if ( self.cleaned_data["pass2"] != self.cleaned_data.get( "pass1", "") ):
			raise forms.ValidationError( "Пароли не совпадают" )
		return self.cleaned_data["pass2"]

class UserProfileForm( forms.ModelForm ):
	weight = forms.IntegerField( min_value = 10, max_value = 200 )

def signup( request ):
	"""Регистрация"""
	user = User()
	userProfile = UserProfile()
	if request.method == "POST":
		userForm = UserForm( request.POST, instance = user )
		userProfileForm = UserProfileForm( request.POST, instance = userProfile )
		if userForm.is_valid() and userProfileForm.is_valid():
			userData = userForm.cleaned_data
			user.username = userData['username']
			user.first_name = userData['firstname']
			user.last_name = userData['lastname']
			user.email = userData['email']
			user.set_password( userData['pass1'] )
			user.save()

			userProfile = user.get_profile()
			userProfileData = userProfileForm.cleaned_data
			userProfile.weight = userProfileData['weight']
			userProfile.save()
			user = authenticate( username = userData['username'], password = userData['pass1'] )
			login(request, user)
			return HttpResponseRedirect( "/accounts/profile/" )
	else:
		userForm = UserForm( instance = user )
		userProfileForm = UserProfileForm( instance = userProfile )
	return render_to_response( "accounts/signup.html", { "user_": user, "userProfile": userProfile, "userForm": userForm, "userProfileForm": userProfileForm }, context_instance = RequestContext( request ) )

@login_required
def my_profile( request ):
	"""Профиль текущего пользователя"""
	user = request.user
	return render_to_response( "accounts/card.html", { "user": user }, context_instance = RequestContext( request ) )

LEAVE A COMMENT