表单集、外键与一对一关系
我想创建一个注册表单,但不想使用任何外部应用程序。不过,我在用表单集保存外键和一对一关系时遇到了问题。
这是我的 models.py 文件:
class UserProfile(models.Model):
user = models.OneToOneField(User)
avatar = models.ImageField(null=True, blank=True, upload_to='avatar/')
website = models.URLField(null=True, blank=True)
birthday = models.DateField()
country = CountryField()
GENDER_CHOICES = (
('M', 'Male'),
('F', 'Female'),
)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
def __str__(self):
return "UserProfile(models)"
class UserLanguage(models.Model):
user = models.ForeignKey(User)
language = models.CharField(max_length=7, choices=LANGUAGES)
level = models.CharField(max_length=1)
# http://stackoverflow.com/questions/3201018/django-language-codes
def __str__(self):
return "UserLanguage(models)"
这是我的 forms.py 文件:
class RegisterForm(forms.ModelForm):
class Meta:
model = User
fields = ('username', 'password',)
exclude = ('last_login',)
widgets = {'password': forms.PasswordInput(), }
UserProfileFormSet = inlineformset_factory(User, UserProfile, can_delete=False)
UserLanguageFormSet = inlineformset_factory(User, UserLanguage, can_delete=False, extra=1)
这是我的 views.py 文件:
def registration(request):
if request.method == "POST":
user = RegisterForm(request.POST)
user_profile = UserProfileFormSet(request.POST)
user_language = UserLanguageFormSet(request.POST)
if user.is_valid() and user_profile.is_valid() and user_language.is_valid():
u = user.save()
user_profile.user = u
user_profile.save()
user_language.user = u
user_language.save()
else:
user = RegisterForm()
user_profile = UserProfileFormSet()
user_language = UserLanguageFormSet()
return render(request, 'user/registration.html', locals())
然后我遇到了这个错误:
列 'user_id' 不能为 null
我该怎么解决这个问题呢?你们还有其他建议吗?谢谢。
1 个回答
1
你把你的表单集合命名为 user_profile
和 user_language
,这让人有点困惑。其实它们并不是用户的个人资料或语言对象,而是表单集合。所以给它们设置用户属性是没有用的。
这个是可以工作的:
for profile_form in user_profile.forms:
up = profile_form.save(commit=False)
up.user = u
up.save()
for language_form in user_language.forms:
ul = language_form.save(commit=False)
ul.user = u
ul.save()
不过,实际上你应该给东西起个准确的名字。