次のフォームは、常にUserProfile に一致するクエリが存在しないことを返します。私は信号を設定しましたが。
そして、それは inetrpreter から期待されるように動作します。
In [1]: from core.models import User
In [2]: u = User.objects.get(id = 1)
In [3]: user_address = u.get_profile().home_address
In [4]: user_address = '20 St.'
モデル
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfile(models.Model):
url = models.URLField()
home_address = models.TextField()
user = models.ForeignKey(User, unique=True)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
意見
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User, Group
from django import forms
from django.shortcuts import render_to_response
from django.http import HttpResponse
from django.template.context import RequestContext
from django.views.decorators.csrf import csrf_protect
class RegisterForm(UserCreationForm):
"""
Hacking the UserCreationForm class by creating a child class,
and overriding the save mthod .save().
Now it should provide email, first_name and last_name fields.
"""
permission_choices = (
('1', 'test1'),
('2', 'test2'),
)
email = forms.EmailField(required=False)
first_name = forms.CharField(required=False)
last_name = forms.CharField(required=False)
url = forms.URLField()
permission = forms.ChoiceField(choices=permission_choices)
class Meta(UserCreationForm.Meta):
model = User
fields = ('first_name', 'last_name', 'url', 'username', 'email', 'password1', 'password2', 'permission')
def save(self, commit=True):
user = super(RegisterForm, self).save(commit=False)
user_profile = user.get_profile()
user.email = self.cleaned_data['email']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.permission = self.cleaned_data['permission']
user_profile.url = self.cleaned_data['url']
if commit:
user.save()
user_profile.save()
return user
@csrf_protect
def register(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
new_user = form.save()
if new_user.permission == '1':
try:
new_user.groups.add(Group.objects.get(name='test1'))
except Group.DoesNotExist:
u = User.objects.get(pk=new_user.pk)
u.delete()
return HttpResponse('The Organisation you\'ve just choosed doesn\' exist')
return HttpResponse('OK')
else:
form = RegisterForm()
return render_to_response('registration/user.html', {'form': form}, context_instance=RequestContext(request))
cberner が言ったように、それは次の理由によると思います。
super(RegisterForm, self).save(commit=False) を呼び出すため、そのエラーが発生していると思います。commit=False を使用すると、モデルは実際にはデータベースにコミットされていないため、Django は post_save シグナルを発行しません。
解決策は次のとおりです。
def save(self, commit=True):
user = super(RegisterForm, self).save(commit=False)
user.email = self.cleaned_data['email']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.permission = self.cleaned_data['permission']
user.save()
user_profile = UserProfile(user=user, url=self.cleaned_data['url'])
if commit:
user_profile.save()
return user