Reputation: 83
I have a model that has a IntegerField
and in the admin. I want to add choices to the widget as "University" field. There is no problem if I add the universities in list as uniList
.
But I do not know how can add these universities from UniversityList
Class. I want to add new universities to UniversityList
on admin panel and then I want to choose these added universities in Mainland2
admin page.
In this case I received error message as
in get raise self.model.MultipleObjectsReturned(mainpage.models.MultipleObjectsReturned: get() returned more than one UniversityList -- it returned 5!
Thank you for in advance...
from django.db import models
from django import forms
from django_countries.fields import CountryField
from django.core.exceptions import ValidationError
class UniversityList(models.Model):
name = models.CharField(max_length=50)
class Mainland2(models.Model):
unilist = [
(0, "---"),
(1, "Uni 1"),
(2,"Uni 2"),
(3,"Uni 3"),
]
graduatedList=[
(0, "Diğer"),
(1, "Lise"),
(2, "Lise (Öğrenci)"),
(3, "Ön Lisans"),
(4, "Ön Lisans (Öğrenci)"),
(5, "Lisans"),
(6, "Lisans (Öğrenci)"),
(7, "Yüksek Lisans"),
(8, "Yüksek Lisans (Öğrenci)"),
(9, "Doktora"),
(10, "Doktora (Öğrenci)")
]
def validate_digit_length(idName):
if not (idName.isdigit() and len(idName) == 11):
raise ValidationError('%(idName)s en az 11 karakter olmalıdır', params={'idName': idName}, )
name = models.CharField(max_length=20, verbose_name="Ad")
midName = models.CharField(max_length=20, verbose_name="Orta Ad", null=False, blank=True)
surName = models.CharField(max_length=20, verbose_name="Soy Ad")
university = models.IntegerField(choices=UniversityList.objects.get(),default=0, verbose_name="Son Mezun Olunan Üniversite")
graduated = models.IntegerField(choices=graduatedList, default=0, verbose_name="Tahsil Durumu")
def __str__(self):
return f"{self.name},{self.surName}"
class Meta:
db_table = "mainland2"
verbose_name_plural = "Ar-Ge Personeller"
Upvotes: 0
Views: 826
Reputation: 12849
Doing objects.get()
like that will try to get 1 object from the database, but you've got 5 by the sounds of it.
Something like objects.first()
would work, but also it's a bad idea to perform that operation on the database in the model like that. You should override forms to perform the database operation in the creation of the form.
So, keep the field on the model simple;
university = models.IntegerField(default=0, verbose_name="Son Mezun Olunan Üniversite")
Then setup the choices in any forms which use the model. An example of this would look like;
class Mainland2Form(forms.ModelForm):
""" Mainland2 form """
class Meta:
""" Setup the form """
model = Mainland2
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
unis = UniversityList.objects.values_list(
'id', 'name'
)
# Make sure we've got an empty choice to avoid people not using the field taking the first choice
uni_choices = \
[(None, '')] + [(u[0], u[1]) for u in list(unis)]
self.fields['university'].choices = uni_choices
You can then override the admin form for your admin class. Check out these docs; https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form
What you probably want though, given you're doing this in admin, is just a ForeignKey
relationship. Django will then handle the choices for you.
And when it comes to FK relationships in admin, you should consider the additional overhead of having to select all the related objects in order to generate the select box.
If the related model has a lot of objects, you can reduce this database query by using raw_id_fields
on your model admin.
For example;
class Mainland2Admin(admin.ModelAdmin):
raw_id_fields = ("university",)
Upvotes: 0