简体   繁体   中英

Django 1.6 adding custom fields to the User model

I've got the following

profile/models.py

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    university = models.CharField(max_length=200, choices=UNIVERSITY, null=True)

profile/views.py

class UserForm(ModelForm):
    class Meta:
        model = UserProfile
        fields = ('username', 'first_name', 'last_name', 'email', 'university')

I've run south and the database is up to date but I still get this error

django.core.exceptions.FieldError: Unknown field(s) (first_name, username, email, last_name) specified for UserProfile

I'm guessing it's something to do with the way the tables are linked. In my UserProfile table I have id, user_id, and university columns with appropriate data in them.

A ModelForm can only generate form fields for a single model, in this case UserProfile . The fields attribute in your meta class specifies which form fields to display. In this case, the fields first_name , username , email and last_name are not defined. You'll have to manually define them on your form, and alter the save method to save the User object:

class UserForm(forms.ModelForm):
    username = forms.CharField(max_length=100)
    email = forms.EmailField()
    ...

    class Meta:
        model = UserProfile
        fields = ('username', 'first_name', 'last_name', 'email', 'university')

    def save(self, commit=True):
        # save user and profile

A ModelForm can only generate fields for a single model (the one specified in the Meta class)

The Django way to have a form with fields for related models is an Inline formset:
https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#inline-formsets

eg

# forms.py
UserProfileFormSet = inlineformset_factory(User, UserProfile, max_num=1)

# views.py
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404, render_to_response
from .forms import UserProfileFormSet

def myview(request, user_id):
    user = get_object_or_404(User, pk=user_id)
    formset = UserProfileFormSet(request.POST or None, instance=user)
    if formset.is_valid():
        formset.save()
        # ...redirect here
    return render_to_response("my_template.html", {
        "formset": formset,
    })

I solved this in the end by substituting a custom User model . This allowed me to set all the user fields in one table called profiles_users and have extra fields.

There is some customisation to set up but I found this approach much more fluid than extending the User base class, personally.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM