Alex
Alex

Reputation: 6037

Form for (extended) User

I have extended my User model and added some extra fields. I want to be able to add new users through a web-interface (not admin-pages), so it needs some form. How can I create this new user in the database and what would the form(s) look like?

class MyUser(models.Model):
     user     = models.OneToOneField(User)
     custcode = models.CharField(max_length=30)

// this obviously doesn't work, but it is a start

from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User

class UserCreateForm(UserCreationForm):

    class Meta:
        model = User
        fields = ('username', 'custcode')

Upvotes: 2

Views: 59

Answers (2)

Muhammad Hassan
Muhammad Hassan

Reputation: 14391

You can do this like this

class UserCreateForm(UserCreationForm):
    custcode = form.CharField()

    class Meta:
        model = User
        fields = ('username', 'custcode')

And write custom save function for you form like this

def save(self, commit=True):
    user = super(UserCreateForm, self).save(commit=True)
    myuser = MyUser.objects.get_or_create(user=user)[0]
    myuser.save()

Upvotes: 1

Antoine Pinsard
Antoine Pinsard

Reputation: 34922

Since you have two models, you need two forms.

One form for auth.User and one for yourapp.MyUser.

In your view, you will:

  1. Instantiate both forms
  2. Check that both forms are valid
  3. Save User form
  4. Save MyUser form, using user.pk

This should give something like that

class MyUserCreationForm(forms.ModelForm):
    class Meta:
        model = User
        exclude = ('user',)
        # Exclude 'user' because we will set it manually

class MyView(View):

    def get(self, request):
        user_form = UserCreationForm(prefix='user')
        myuser_form = MyUserCreationForm(prefix='myuser')
        # Use prefix to avoid name conflicts
        return render(...)

    def post(self, request):
        user_form = UserCreationForm(request.POST, prefix='user')
        myuser_form = MyUserCreationForm(request.POST, prefix='myuser')
        user_form_is_valid = user_form.is_valid()
        myuser_form_is_valid = myuser_form.is_valid()
        # Do form.is_valid() here in order to always call both
        if user_form_is_valid and myuser_form_is_valid:
            user = user_form.save()
            myuser = myuser_form.save(commit=False)
            myuser.user = user
            myuser.save()
            ...
        ...
        return ...

For the sake of consistency, forms saving should be included in a transaction as well. But that's another topic.

Upvotes: 2

Related Questions