2012-06-04 48 views
0

我對Django非常陌生,我試圖創建一個註冊表單。這是我的模式的相關部分:Django中的UserCreationForm當存在外鍵時帶有額外字段

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 

    university = models.ForeignKey('University') 
    course_title = models.ForeignKey('Course_Title') 

    class Meta: 
     db_table = 'user_profile' 

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 import forms 
from django.contrib.auth.models import User 
from shelf.models import University, Course_Title, UserProfile 

class RegistrationForm(UserCreationForm): 

error_messages = { 
    'duplicate_email': "A user with that e-mail already exists.", 
    'email_mismatch': "The two e-mail fields didn't match.", 
} 

# An e-mail is being used instead of the usual Django username. 
username = forms.EmailField(label="E-mail") 
username2 = forms.EmailField(label="Confirm E-mail") 
university = forms.ModelChoiceField(queryset=University.objects.all(), empty_label="Please choose a university") 
course_title = forms.ModelChoiceField(queryset=Course_Title.objects.all(), empty_label="Please choose a course title") 

class Meta: 
    model = User 
    fields = ("first_name", "last_name", "university", "course_title", "username", "username2") 

    . 
    . 
    . 

def save(self, commit=True): 
    user = super(RegistrationForm, self).save(commit=False) 
    user.save() 
    user_profile = UserProfile(user=user, university=self.cleaned_data["university"], course_title=self.cleaned_data["course_title"]) 
    if commit: 
     user_profile.save() 
    return user_profile 

而且,這是我的觀點

def index(request): 
    if request.method == 'POST': 
     form = RegistrationForm(request.POST) 
     if form.is_valid(): 
      new_user = form.save() 
      return HttpResponseRedirect("/") 
    else: 
     form = RegistrationForm() 

    return render(request, "shelf/register.html", {'form': form, }) 

我得到錯誤user_profile.university_id可能不是NULL。我已經看了很多爲什麼發生這種情況,我明白爲什麼會發生。但我似乎無法解決它。

在此先感謝。

回答

0

它看起來像問題是由信號處理造成的:

def create_user_profile(sender, instance, created, **kwargs): 
    if created: 
     UserProfile.objects.create(user=instance) # no university here 

post_save.connect(create_user_profile, sender=User) 

請重試禁用此處理程序和測試。

如果你想在信號處理程序,請嘗試改變form.save方法:

def save(self, commit=True): 
    user = super(RegistrationForm, self).save(commit=False) #this should trigger the signal handler to create a UserProfile instance, but not commit 
    user_profile = user.get_profile() 
    user_profile.university=self.cleaned_data["university"] 
    user_profile.course_title=self.cleaned_data["course_title"] 
    if commit: 
     user.save() 
     user_profile.save() 

要小心,如果你創建在shell用戶,你仍然得到同樣的錯誤,我想也許你可以爲大學和COURSE_TITLE領域的用戶配置模型添加默認值:

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 

    university = models.ForeignKey('University', default=1) 
    course_title = models.ForeignKey('Course_Title', default=1) 
+0

太謝謝你了。這工作。我不明白爲什麼這是。我讀過我需要添加此信號處理程序,如果我使用用戶配置文件(向用戶添加字段)。有什麼我可以添加到信號處理程序讓它回來? –

0

我有同樣的問題,但解決不了它,雖然我也跟着步驟

型號

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): 
    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 == 'q': 
       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))