Okay so this is a Django project I'm starting, and I have a User
model in models.py
. It has nested models, the 'contact' model and the 'personal' model. I want to create a form in Django.
class User(models.Model):
"""
Model representing a User with field groups
"""
class ContactInfo(models.Model):
email = models.EmailField(
max_length=120,
validators=[EmailValidator()],
unique=True,
verbose_name="Contact Email"
)
phone = models.CharField(
max_length=10,
blank=True,
null=True,
verbose_name="Phone Number"
)
address = models.CharField(
max_length=100,
validators=[MinLengthValidator(5)],
verbose_name="Address"
)
suite = models.CharField(
max_length=20,
validators=[MinLengthValidator(0)],
verbose_name="Suite"
)
city = models.CharField(
max_length=50,
validators=[MinLengthValidator(3)],
verbose_name="City"
)
state = models.CharField(
max_length=2,
validators=[MinLengthValidator(2)],
verbose_name="State"
)
zip_code = models.CharField(
max_length=5,
validators=[MinLengthValidator(5)],
verbose_name="Zip Code"
)
class PersonalInfo(models.Model):
first_name = models.CharField(
max_length=40,
validators=[MinLengthValidator(2)],
verbose_name="First Name"
)
last_name = models.CharField(
max_length=40,
validators=[MinLengthValidator(2)],
verbose_name="Last Name"
)
company = models.CharField(
max_length=100,
validators=[MinLengthValidator(5)],
verbose_name="Company Name"
)
contact = models.OneToOneField(
ContactInfo,
on_delete=models.CASCADE,
related_name='user_contact'
)
personal = models.OneToOneField(
PersonalInfo,
on_delete=models.CASCADE,
related_name='user_personal'
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.personal.first_name} {self.personal.last_name}"
from django import forms
from .models import User, Request
class UserForm(forms.ModelForm):
"""
Form for users
"""
class Meta:
model = User
fields = (
'personal.first_name',
'personal.last_name',
'personal.company',
'contact.email',
'contact.phone',
'contact.address',
'contact.suite',
'contact.city',
'contact.state',
'contact.zip_code',
)
def save(self, commit=True):
user = super().save(commit=False)
contact_info, _ = User.ContactInfo.objects.get_or_create(
email=self.cleaned_data['contact.email'],
phone=self.cleaned_data['contact.phone'],
address=self.cleaned_data['contact.address'],
suite=self.cleaned_data['contact.suite'],
city=self.cleaned_data['contact.city'],
state=self.cleaned_data['contact.state'],
zip_code=self.cleaned_data['contact.zip_code']
)
personal_info, _ = User.PersonalInfo.objects.get_or_create(
first_name=self.cleaned_data['personal.first_name'],
last_name=self.cleaned_data['personal.last_name'],
company=self.cleaned_data['personal.company']
)
user.contact = contact_info
user.personal = personal_info
if commit:
user.save()
return user
I am getting the following error.
File "/develop/repos/template_py/django_template/django_template/urls.py", line 21, in <module>
from django_template_app import views
File "/develop/repos/template_py/django_template/django_template_app/views.py", line 10, in <module>
from .forms import UserForm, RequestForm
File "/develop/repos/template_py/django_template/django_template_app/forms.py", line 5, in <module>
class UserForm(forms.ModelForm):
File "/home/matt/.local/share/virtualenvs/template_py-7Odno36H/lib/python3.12/site-packages/django/forms/models.py", line 334, in __new__
raise FieldError(message)
django.core.exceptions.FieldError: Unknown field(s) (contact.city, contact.state, contact.email, personal.company, contact.suite, contact.address, personal.last_name, personal.first_name, contact.zip_code, contact.phone) specified for User
class ContactInfoForm(forms.ModelForm):
class Meta:
model = ContactInfo
fields = ['email', 'phone', 'address', 'suite', 'city', 'state', 'zip_code']
class PersonalInfoForm(forms.ModelForm):
class Meta:
model = PersonalInfo
fields = ['first_name', 'last_name', 'company']
class UserForm(forms.ModelForm):
contact_form = ContactInfoForm(prefix="contact")
personal_form = PersonalInfoForm(prefix="personal")
class Meta:
model = User
fields = []
def __init__(self, *args, **kwargs):
contact_data = kwargs.pop('contact_data', None)
personal_data = kwargs.pop('personal_data', None)
super().__init__(*args, **kwargs)
self.contact_form = ContactInfoForm(contact_data, prefix="contact")
self.personal_form = PersonalInfoForm(personal_data, prefix="personal")
def is_valid(self):
return super().is_valid() and self.contact_form.is_valid() and self.personal_form.is_valid()
def save(self, commit=True):
user = super().save(commit=False)
contact_info = self.contact_form.save(commit=commit)
personal_info = self.personal_form.save(commit=commit)
user.contact = contact_info
user.personal = personal_info
if commit:
user.save()
return user
Would you try this?