0

以下表单始终返回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
4

1 回答 1

2

我相信您会收到该错误,因为您致电super(RegisterForm, self).save(commit=False). 如果您使用commit=FalseDjango,则不会发出 post_save 信号,因为模型实际上并未提交给数据库。

于 2012-06-05T06:13:11.453 回答