Suppose below models:
from django.db import models
class Status:
name = models.CharField(max_length=50)
order = models.PositiveIntegerField()
def __str__(self):
return self.name
class Article:
headline = models.CharField(max_length=100)
status = models.ForeignKey(Status, on_delete=models.CASCADE, null=True)
I want to create admin form for Article
model, but don't want to use results of __str__
method of Status
model as display name in status choices form field. It can be achieved by overriding label_from_instance
method ModelChoiceField
as below:
from django import forms
from blog.models import Status, Article
class StatusModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, status):
label = f"{status.order}: {status.name}"
return label
class ArticleForm(forms.ModelForm):
status = StatusModelChoiceField(queryset = Status.objects.all())
class Meta:
model = Article
fields = ('headline', 'status')
Problem with this method is that, it doesn't take into account Article
model's status
field definition. For example, although status
field is nullable in Article
model, it is required in ArticleForm
. I should tell explicitly that it is not required ( status = StatusModelChoiceField(queryset = Status.objects.all(), required=False)
). If status
field would have limit_choices_to
, it also won't be considered in my form dynamically.
So, I just want different display names than default __str__
. How can I achieve this goal in more DRY manner?
Although you will have to make the custom field inheriting from ModelChoiceField
, what you can do is set it as the class to be used for your field by using the field_classes
attribute one can set on the forms Meta
(Reference Overriding the default fields [Django docs] ):
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ('headline', 'status')
field_classes = {
'status': StatusModelChoiceField,
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.