Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use method other than __unicode__ in ModelChoiceField Django

I'm working on some forms in Django. One field is a ForeignKey in the model, so represented as a ModelChoiceField in the form. The ModelChoiceField currently uses the __unicode__ method of the model to populate the list, which isn't my desired behavior. I'd like to be able to use another method of the model. From the docs, it looks like I can force my own QuerySet, but I can't see how this would help me use a method other than __unicode__.

I'd really rather avoid divorcing this from the default form methods if at all possible.

Any suggestions?

like image 477
TimD Avatar asked Jul 11 '12 16:07

TimD


2 Answers

You can override label_from_instance to specify a different method:

from django.forms.models import ModelChoiceField

class MyModelChoiceField(ModelChoiceField):

    def label_from_instance(self, obj):
        return obj.my_custom_method()

You can then use this field in your form instead. This method is intended to be overridden in subclasses. Here is the original source in django.forms.models:

# this method will be used to create object labels by the QuerySetIterator.
# Override it to customize the label.
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.
    """
    return smart_unicode(obj)
like image 96
Simeon Visser Avatar answered Oct 04 '22 17:10

Simeon Visser


Not so much a custom queryset, but converting your queryset to a list. If you just do choices=some_queryset Django makes the choices in the form of:

(item.pk, item.__unicode__())

So just do it yourself with a list comprehension:

choices=[(item.pk, item.some_other_method()) for item in some_queryset]
like image 27
Chris Pratt Avatar answered Oct 04 '22 18:10

Chris Pratt