customize select in django admin

2020-07-10 10:47发布

问题:

I have a model, one field of it is a ForeignKey, so i see select in django admin, is it possiable to customize labels of this select?



class Model(models.Model):
    name = models.CharField()
    def __unicode__(self):
         return self.name

class Part(models.Model):
    name = models.CharField()
    parent =  model.ForeignKey(Model)
    def __unicode__(self):
         return self.name
    def name_with_model(self):
         return self.name + ' ' + parent.name

class SmallPart(models.Model):
    name = models.CharField()
    parent =  model.ForeignKey(Part)

when I add new SmallPart I see select tag with names of parts, I need to see name_with_model

回答1:

If you mean the field label:

using code from: Django Admin - Overriding the widget of a custom form field

# forms.py

from django import forms
from django.contrib import admin

class ProductAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ProductAdminForm, self).__init__(*args, **kwargs)
        self.fields['tags'].label = 'Custom Label'

Then, in your ModelAdmin object, you specify the form:

from django.contrib import admin
from models import Product
from forms import ProductAdminForm

class ProductAdmin(admin.ModelAdmin):
    form = ProductAdminForm

admin.site.register(Product, ProductAdmin)

If you mean the labels in the select drop down:

Override the widget like in the answer above.

edit:

The default form field for a fk field is a model choice field. From the docs

The unicode method of the model will be called to generate string representations of the objects for use in the field's choices; to provide customized representations, subclass ModelChoiceField and override label_from_instance. This method will receive a model object, and should return a string suitable for representing it. For example:

class MyModelChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        return obj.name_with_model()

and then:

class SmallPartAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(SmallPartAdminForm, self).__init__(*args, **kwargs)
        self.fields['parent'] = MyModelChoiceField(queryset=Part.objects.all())