Django admin foreign key dropdown with custom value
2 Options.
Option 1:
Create a new field
, copy forms.ModelChoiceField
and override label_from_instance
.
# From the source
class PageModelChoiceField(forms.ModelChoiceField():
def label_from_instance(self, obj):
"""
This method is used to convert objects into strings; it's used to
generate the labels for the choices presented by this object. Subclasses
can override this method to customize the display of the choices.
"""
# Then return what you'd like to display
return "Page{0} - Test{1}".format(obj.pk, obj.test.pk)
This will only change the text for that particular dropdown field. As you are accessing the Test
object for each item in the list, you may want to ensure the queryset
you pass to the PageModelChoiceField
has select_related('test')
, otherwise it will make a DB hit for each item on the list.
I've not tested this exact code but the logic is there. Will try it later when I can
class QuestionForm(forms.ModelForm):
page = PageModelChoiceField(
queryset=Page.objects.select_related('test').all()
)
class Meta:
model = Page
class QuestionAdmin(ModelAdmin):
class Meta:
model = Question
form = QuestionForm
Option B.
Change the unicode() representation of Page
.
class Page(models.Model):
test = models.ForeignKey(Test)
def __unicode__(self):
return "Page{0} - Test{1}".format(obj.pk, obj.test.pk)
This will change how Page
s are displayed everywhere you print a page object, print(page_object)
, {{ page_object }}
.
Personally I prefer Option 1
Related videos on Youtube
linkyndy
Passionate about everything web-related. Love cycling, snooker, swimming and traveling.
Updated on September 24, 2022Comments
-
linkyndy about 1 year
I have 3 Django models:
class Test(models.Model): pass class Page(models.Model): test = models.ForeignKey(Test) class Question(model.Model): page = models.ForeignKey(Page)
If I register the
Question
model to the admin, I get a dropdown with the desiredPage
. Now, what do I have to modify to display the desiredPage
plus that page's correspondingTest
?Say, if I have three pages created, the dropdown will contain these values:
Page1
,Page2
,Page3
. I would like to see:Page1 - Test1
,Page2 - Test1
,Page3 - Test1
-
linkyndy about 10 yearsThanks for your detailed answer!
-
rockingskier about 10 yearsHappy to help. I always prefer full answers so thought it best to provide them myself as well :)
-
Siddaram H almost 6 yearsThank you.. Option B made my day.. used 'self.<var>' instead of 'obj.pk'
-
Nic almost 2 yearsThe reason this answer got downvoted is that it suggest universally overriding the string representation of the model instance. I believe the question implies that they only want the string representation to be custom in the admin/