【问题标题】:Django Admin foreign key, more detailedDjango Admin外键,更详细
【发布时间】:2015-10-29 17:02:17
【问题描述】:

我正在尝试自定义我的管理员。我有一个模型与另一个模型的外键。我目前有一个下拉列表,显示可供选择的可能键列表,但列表仅显示标题。

模型.py

class Equipment(models.Model):
    noequipment = models.IntegerField('Equipment #' ,db_column='Noequipment', primary_key=True)  # Field name made lowercase.
    nom = models.CharField('Name',db_column='Nom', max_length=50, blank=True)  # Field name made lowercase.
    ...
    nooffice = models.ForeignKey('Office', db_column='NoOffice', blank=True, null=True, verbose_name='Office')  # Field name made lowercase.
    ...

    class Meta:
        db_table = 'equipment'
        ordering = ('nom',)

    def __str__(self):
        return self.nom


class Office(models.Model):
    nooffice = models.IntegerField(db_column='NoOffice', primary_key=True)  # Field name made lowercase.
    officename = models.CharField(db_column='OfficeName', max_length=50, blank=True)  # Field name made lowercase.
    adresse = models.CharField(db_column='Adresse', max_length=50, blank=True)  # Field name made lowercase.
    ville = models.CharField(db_column='Ville', max_length=50, blank=True)  # Field name made lowercase.
    codepostal = models.CharField(db_column='CodePostal', max_length=50, blank=True)  # Field name made lowercase.

    class Meta:
        db_table = 'office'

    def __str__(self):
        return self.officename

我只需要管理员在下拉列表顶部显示一个包含属性值的表格。

这里也是 admin.py(需要特殊的 ModelAdmin,因为我使用多个数据库,根据 https://docs.djangoproject.com/en/1.8/topics/db/multi-db/

from django.contrib import admin
from .models import Equipment, Manufacturier, Office, Devicetype, Backdoor, Passage, Systadmin, Applicationadmin, Application, Os
from django import forms
from forms import EquipmentAdminForm, ManufacturierAdminForm, OfficeAdminForm, DevicetypeAdminForm, BackdoorAdminForm, PassageAdminForm, SystadminAdminForm, ApplicationadminAdminForm, ApplicationAdminForm, OsAdminForm

class VCOEModelAdmin(admin.ModelAdmin):
# A handy constant for the name of the alternate database.
    using = 'vcoe'

    def save_model(self, request, obj, form, change):
        # Tell Django to save objects to the 'other' database.
        obj.save(using=self.using)

    def delete_model(self, request, obj):
        # Tell Django to delete objects from the 'other' database
        obj.delete(using=self.using)

    def get_queryset(self, request):
        # Tell Django to look for objects on the 'other' database.
        return super(VCOEModelAdmin, self).get_queryset(request).using(self.using)

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        # Tell Django to populate ForeignKey widgets using a query
        # on the 'other' database.
        return super(VCOEModelAdmin, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs)

    def formfield_for_manytomany(self, db_field, request=None, **kwargs):
        # Tell Django to populate ManyToMany widgets using a query
        # on the 'other' database.
        return super(VCOEModelAdmin, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs)

class VCOETabularInline(admin.TabularInline):
    using = 'vcoe'

    def get_queryset(self, request):
        # Tell Django to look for inline objects on the 'other' database.
        return super(VCOEMTabularInline, self).get_queryset(request).using(self.using)

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        # Tell Django to populate ForeignKey widgets using a query
        # on the 'other' database.
        return super(VCOEMTabularInline, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs)

    def formfield_for_manytomany(self, db_field, request=None, **kwargs):
        # Tell Django to populate ManyToMany widgets using a query
        # on the 'other' database.
        return super(VCOEMTabularInline, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs)

class OfficeAdmin(VCOEModelAdmin):
    form = OfficeAdminForm

class EquipmentAdmin(VCOEModelAdmin):
    form = EquipmentAdminForm

...

admin.site.register(Equipment, EquipmentAdmin)
...
admin.site.register(Office, OfficeAdmin)
...

和forms.py

from django import forms
from .models import Equipment, Manufacturier, Office, Devicetype, Backdoor, Passage, Systadmin, Applicationadmin, Application, Os

class EquipmentAdminForm(forms.ModelForm):
    class Meta:
        model = Equipment
        exclude = ['noequipment']

...

class OfficeAdminForm(forms.ModelForm):
    class Meta:
        model = Office
        exclude = ['nooffice']

【问题讨论】:

    标签: django django-models django-admin


    【解决方案1】:

    我看到了两种可能的方法:

    1. 最简单的方法是在您的模型上创建__str__(或__unicode__,取决于on Python version)以包含您想要查看的额外信息。例如:

      class Office(models.Model):
          ...
          def __unicode__(self):
              return u"{0.officename} ({0.ville}, {0.addresse})".format(self)
      
    2. 最灵活但最复杂的是创建自定义小部件。有一些现成的库可能适合也可能不适合您的需求和口味。例如,您可以考虑查看django-autocomplete-lightModelChoiceField 和它的autocomplete styling options

      过程并不简单,但总体大纲是:

      1. 创建自己的widget 课程或学习现成的东西。
      2. 创建一个使用此小部件的ModelForm。一些库提供了一个预先配置为使用小部件的自定义字段,如果您有一个自行实现的,您可以考虑编写一个字段或使用 Django 的内置 ModelChoiceFieldwidget 参数。有些库有自己的约定,如果你有自己的实现,那么你可以使用类似的东西:

        class EquipmentForm(forms.ModelForm):
            class Meta:
                model = Equipment
                widgets = {
                    "office": OfficeSelectWidget(...)
                }
        
      3. 在您的 ModelAdminrefer to your form 中,因此 Django 将使用它而不是自动生成的。

    如果您只是在试验或学习 - 并且有足够的空闲时间,我建议您走复杂的路线并自己编写所有内容,这样您就会知道事情的运作方式。然后再也不要这样做了,而是使用 PyPI 的电池。如果你只是想要快速,看看上面提到的django-autocomplete-light 库,它应该很容易上手。只需按照他们的教程和示例进行操作,从基本的自动完成字段开始,然后使用自定义样式对其进行扩展。

    【讨论】:

    • __unicode__ 仅在 Python 2 中正确。如果 OP 使用 Python 3,__str__ 是正确的。这与任何 Django 的“魔法”无关。
    • @DanielRoseman 确实,我错了 - 仍然坚持使用 2.7,很少看 3.x。更新了答案,谢谢提醒。
    猜你喜欢
    • 2020-06-26
    • 2016-09-29
    • 2018-09-13
    • 2020-07-10
    • 2018-09-19
    • 2012-09-16
    • 1970-01-01
    • 2012-02-19
    • 2014-03-16
    相关资源
    最近更新 更多