Seckinyilmaz
Seckinyilmaz

Reputation: 83

Django Admin Panel Choices from Database

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

Answers (1)

markwalker_
markwalker_

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",)

https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.raw_id_fields

Upvotes: 0

Related Questions