来自数据库的 Django 管理面板选择

Django Admin Panel Choices from Database

我有一个模型 IntegerField 并且在管理员中。我想将选项添加到小部件作为“大学”字段。如果我将列表中的大学添加为 uniList.

就没有问题

但我不知道如何从 UniversityList Class 添加这些大学。我想在管理面板上向 UniversityList 添加新大学,然后我想在 Mainland2 管理页面中选择这些添加的大学。

在这种情况下,我收到的错误消息为

in get raise self.model.MultipleObjectsReturned(mainpage.models.MultipleObjectsReturned: get() returned more than one UniversityList -- it returned 5!

提前感谢您...

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"

像那样objects.get()会尝试从数据库中获取 1 个对象,但听上去你已经得到了 5 个对象。

objects.first()这样的东西会起作用,但在这样的模型中对数据库执行该操作也是一个坏主意。您应该覆盖表单以在创建表单时执行数据库操作。

因此,请保持模型上的字段简单;

university = models.IntegerField(default=0, verbose_name="Son Mezun Olunan Üniversite")

然后在使用该模型的任何形式中设置选项。这方面的一个例子看起来像;


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

然后您可以覆盖管理员的管理表单 class。查看这些文档; https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form

虽然您在管理员中执行此操作,但您可能想要的只是 ForeignKey 关系。然后 Django 将为您处理这些选择。

当涉及到管理中的 FK 关系时,您应该考虑必须 select 所有相关对象才能生成 select 框的额外开销。

如果相关模型有很多对象,您可以在模型管理员上使用 raw_id_fields 来减少此数据库查询。

例如;

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