django.core.exceptions.FieldError: Unknown field(s) (username) specified for Employee

Viewed 10905

I am trying to extend the user model

so I created a new model called employee with foreignkey to user model

from django.db import models

from django.contrib.auth.models import User

class Employee(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    department = models.CharField(max_length=200)

and tried to create a form for the signup

from django.contrib.auth.forms import UserCreationForm
from employee.models import Employee

class EmployeeForm(UserCreationForm):
    class Meta(UserCreationForm.Meta):
        model = Employee
        fields = UserCreationForm.Meta.fields + ('department',)

These are the only changes I made I am getting the following error:

File "/home/sugumar/python/django/project1/project1/urls.py", line 18, in from employee.views import signup File "/home/sugumar/python/django/project1/employee/views.py", line 2, in from .forms import EmployeeForm File "/home/sugumar/python/django/project1/employee/forms.py", line 4, in class EmployeeForm(UserCreationForm): File "/home/sugumar/.local/share/virtualenvs/project1-j0yhUYNK/lib/python3.5/site-packages/django/forms/models.py", line 266, in new raise FieldError(message) django.core.exceptions.FieldError: Unknown field(s) (username) specified for Employee

2 Answers

I am trying to extend the user model, so I created a new model called employee with foreignkey to user model.

By using a OneToOneField, one can indeed extend the user system, but you can not simply use this to handle both models in the same Form, and thus construct two objects at once.

What you here basically construct is a ModelForm on the Employee model, but here you have constructed a Meta class with extra fields, but these fields are not related to model fields on the Employee object, hence the error.

Probably it is better to simply construct two forms, so the Employee-form looks like:

# app/forms.py

from django.forms import ModelForm

class EmployeeForm(ModelForm):

    class Meta:
        model = Employee
        fields = ('department',)

and then create a view like:

# app/views.py

from django.contrib.auth.forms import UserCreationForm
from app.forms import EmployeeForm

def create_user(request):
     if request.method == 'POST':
        user_form = UserCreationForm(request.POST)
        employee_form = EmployeeForm(request.POST)
        if user_form.is_valid() and employee_form.is_valid():
            user = user_form.save()
            employee = employee_form.save(commit=False)
            employee.user = user
            employee.save()
            return redirect('...')
    else:
        user_form = UserCreationForm()
        employee_form = EmployeeForm()
    return render(
        request,
        'app/my_template.html',
        {'user_form': user_form, 'employee_form': employee_form}
    )

In the view we will thus, given both forms are valid, create a User and Employee object and link the employee to the user. We furthermore render the template with two forms.

In the template, we render the two forms in the same <form> tag:

<!-- app/templates/app/my_template.html -->

<form action="{% url 'app:create_user' %}" method="post">
    {% csrf_token %}
    {{ user_form }}
    {{ employee_form }}
</form>

Where 'app:create_user' is the name of the URL that points to the view defined above.

I had the same issue.

I solved it deleting all the references to Employee. Then:

python manage.py migrate

And finally adding Employee and finishing the migration:

python manage.py makemigrations        
python manage.py migrate
Related