Django: переопределить get_FOO_display()

В общем, я не знаком с путём переопределения методов python и с помощью функции super().

вопрос: могу ли я переопределить get_FOO_display()?

class A(models.Model):
   unit = models.IntegerField(choices=something)

   def get_unit_display(self, value):
     ... use super(A, self).get_unit_display() 

Я хочу переопределить get_FOO_display(), потому что хочу разделить мой экран.

Но super(A, self).get_unit_display() не работает.

Ответ 1

Обычно вы просто переопределяете метод, как вы показали. Но хитрость здесь в том, что метод get_FOO_display отсутствует в суперклассе, поэтому вызов метода super ничего не даст. Метод добавляется динамически классом поля, когда он добавляется в модель метаклассом - см. Источник здесь (EDIT: устаревшая ссылка в виде постоянной ссылки).

Одна вещь, которую вы могли бы сделать, это определить пользовательский подкласс Field для поля вашего unit и переопределить contribute_to_class чтобы он создавал нужный вам метод. Это немного сложно, к сожалению.

(Я не понимаю ваш второй вопрос. Что именно вы спрашиваете?)

Ответ 2

Вы должны иметь возможность переопределить любой метод в суперклассе, создав метод с таким же именем в подклассе. Подпись аргумента не рассматривается. Например:

class A(object):
    def method(self, arg1):
        print "Method A", arg1

class B(A):
    def method(self):
        print "Method B"

A().method(True) # "Method A True"
B().method() # "Method B"

В случае get_unit_display() вам вообще не нужно называть super(), если вы хотите изменить отображаемое значение, но если вы хотите использовать super(), убедитесь, что вы вызываете его с помощью правильная подпись, например:

class A(models.Model):
    unit = models.IntegerField(choices=something)

    def get_unit_display(self, value):
        display = super(A, self).get_unit_display(value)
        if value > 1:
            display = display + "s"
        return display

Обратите внимание, что мы передаем значение супер() get_unit_display().