Django Admin外键,更详细

时间:2015-08-06 13:50:03

标签: django django-models django-admin

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

model.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

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

enter image description here

此处也是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']

1 个答案:

答案 0 :(得分:2)

我看到两种可能的方法:

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

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

    这个过程并不简单,但整体大纲是:

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

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

  3. 如果您只是在尝试或学习 - 并且有足够的时间闲暇,我建议您走复杂的路线并自己编写所有内容,这样您就可以了解情况如何发挥作用。然后再也不要这样做,而是使用PyPI的电池。如果您只想快速浏览,请查看上面提到的django-autocomplete-light库,这应该非常简单。只需按照他们的教程和示例,从基本自动填充字段开始,然后使用自定义样式扩展它。

相关问题