Reputation: 499
Trying to create a choice field based on another model
I want my choices to be mapped like username: first_name + last_name
When I try username: last_name
it does work
I tried doing something like this(Note, I am adding on user_choices and choices=user_choices. The model already existed before me making these changes.)
This works:
he_user_choices = tuple(User.objects.values_list('username', 'last_name'))
Here's what my models.py looks like:
from django.contrib.auth.models import User
owner_choices = tuple(User.objects.values_list('username', 'first_name' + 'last_name'))
class ErrorEvent(models.Model):
"""Error Event Submissions"""
event_id = models.BigAutoField(primary_key=True)
owner = models.IntegerField(verbose_name="Owner", blank=True, choices=owner_choices)
and here's my forms.py
from django import forms
from .models import ErrorEvent
class ErrorEventForm(forms.ModelForm):
class Meta:
model = ErrorEvent
# fields =
exclude = ['event_id']
widgets = {
'owner': forms.Select(),
}
Currently the owner_choices doesn't work, I get an error that says:
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
Any recommendations on what else I can try, or how would I go about fixing my problem?
Thank you in advance!
Upvotes: 1
Views: 1382
Reputation: 477210
Please do not work with an IntegerField
to refer to an object. A ForeignKey
will check referential integrity, and furthermore it makes the Django ORM more expressive.
You thus can implement this with:
from django.conf import settings
class ErrorEvent(models.Model):
event_id = models.BigAutoField(primary_key=True)
owner = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name='Owner',
blank=True,
null=True
)
This will work with a ModelChoiceField
[Django-doc] that automatically will query the database to render options. This also means that if you add a new User
, creating a new ErrorEvent
can be linked to that user, since it each time requests the User
s from the database.
You can subclass the ModelChoiceField
to specify how to display the options, for example:
from django.forms import ModelChoiceField
class MyUserModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return f'{obj.username} ({obj.firstname} {obj.lastname})'
Then we can use this in the form:
class ErrorEventForm(forms.ModelForm):
owner = MyUserModelChoiceField(queryset=User.objects.all())
class Meta:
model = ErrorEvent
# fields =
exclude = ['event_id']
widgets = {
'owner': forms.Select(),
}
Upvotes: 1