2012-04-24 4 views
2

Здесь я нашел много ответов, где рекомендуемый курс действий при перегрузке данного метода по умолчанию из Django - это просто скопировать код из этого исходного метода и включить его с вашими изменениями в вашу перегруженную версию указанного метода.Является ли моя рекомендация использовать super() неверно?

Например, answer given:

class MyUpdateView(UpdateView): 
    def form_valid(self, form): 
     self.object = form.save(commit=False) 
     self.object.user = self.request.user 
     self.object.save() 
     return HttpResponseRedirect(self.get_success_url()) 

    # the default implementation of form_valid is... 
    # def form_valid(self, form): 
    #  self.object = form.save() 
    #  return HttpResponseRedirect(self.get_success_url()) 

Таким образом, две линии, которые ответчик говорит являются по умолчанию form_valid не на самом деле код по умолчанию, но они код, который запускается на выполнение через наследование. Несмотря на это, их ответ удалил выполнение любого кода Django в начале form_valid и заменил его прямым вызовом HttpResponseRedirect().

Как я хотел бы написать этот метод заключается в следующем: собственный код

class MyUpdateView(UpdateView): 
    def form_valid(self, form): 
     self.object = form.save(commit=False) 
     self.object.user = self.request.user 
     return super(MyUpdateView, self).form_valid(form) 

Джанго следует этому соглашению. Взятые из views/generic/edit.py линии 111:

def form_valid(self, form): 
    self.object = form.save() 
    return super(ModelFormMixin, self).form_valid(form) 

Это истинная версия по умолчанию form_valid что отвечающему этого другого вопроса имеет в виду.

Итак, гайка этого вопроса: Есть ли какая-то причина, по которой я не должен использовать super() таким образом в своих проектах, точно так же, как код Django делает это внутри? Преимущество для меня в том, что если бы Django постоянно обновлял то, как эти представления работают внутри, шансы намного лучше, чем мой код, который просто расширяет и продолжает исполнять Django, будет оставаться совместимым. Кроме того, он не позволяет мне переписывать код, который уже написан простым исполнением существующего кода с изменениями. Разве это не одно из назначений super()?

ответ

3

Да, есть причина.

Давайте заменим ваш звонок super с использованием фактического метода Django.

class MyUpdateView(UpdateView): 
    def form_valid(self, form): 
     self.object = form.save(commit=False) 
     self.object.user = self.request.user 
     self.object = form.save() # oops, we redefined self.object, user won't be saved 
     return HttpResponseRedirect(self.get_success_url()) 

Так что это не сработает. Конечно, использование super всегда DRY'er и лучше, но это не всегда возможно.

В вашем примере из источника Django это еще одна ситуация: ребенок действительно сохраняет и родитель перенаправляет. Здесь нет «перекрытий».

+1

Это просто недопустимая реализация. Мы можем задать пользователю form.instance.user вместо создания объекта, который будет переписан в вызове родителя. В любом случае, если нам нужна функциональность всех родителей, мы должны использовать супер, если нам не нужны какие-то части или вы хотите переопределить их (а не просто добавлять дополнительные действия) - очевидно, нам не нужен супер. – simplylizz

+2

@simplylizz Это будет работать, я думаю, но мне это не нравится. Вместо того, чтобы работать с результатом 'form.save (commit = True)', мы используем его как метод «change in place». Не так хорошо для чтения и понимания кода. – DrTyrsa

 Смежные вопросы

  • Нет связанных вопросов^_^