1

I want to create registration form without use any external app but I do not manage to save foregin and OneToOne relation with a formset. Here my 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)"

Here my 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)

And my 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())

And I get this error :

Column 'user_id' cannot be null

What can I do for resolve my problem ? Have you another remarks ? Thank you.

Oyabi
  • 824
  • 3
  • 10
  • 27

1 Answers1

1

You've confusingly named your formsets user_profile and user_language. But they are not the profile or language objects, they are formsets, so setting their user attribute will have no effect.

This works:

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()

but really you should name things what they are.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Aaaah ok thank you, it's pretty simple and you're right about variable name, i will change it. ;) However I have another error : `'list' object has no attribute 'user'` on line `up.user = u`. Have you an idea ? – Oyabi Jul 10 '14 at 20:35
  • 1
    See my edit - even though I knew those were formsets, not forms, I gave you the syntax for saving forms. Formsets are more complicated when you're adding attributes, as you need to do it per form. – Daniel Roseman Jul 10 '14 at 21:28
  • Thank you very much, that work very well. ;) Have a nice day. – Oyabi Jul 11 '14 at 08:16