Могу ли я использовать утки с просмоткой на основе класса

StackOverflow https://stackoverflow.com/questions/19850375

  •  29-07-2022
  •  | 
  •  

Вопрос

Я могу быть полностью не в резервации здесь. (Не стесняйтесь сказать мне, если я есть.)

Мой вариант использования в том, что у меня есть список школ. Школьная модель довольно проста:

class School(models.Model):
    name = models.CharField(max_length=100)
    mascot = models.CharField(max_length=100, null=True, blank=True)

Когда мой пользователь хочет отредактировать одну из этих школ, я не хочу, чтобы они редактировали мастер -копию. Вместо этого я хочу дать им свою собственную копию, с которой они могут сыграть. Когда они закончат редактирование своей копии, они могут представить свои изменения, а кто -то другой одобрит это. Итак, у меня есть еще один класс для копии пользователя в школе:

class UserSchool(models.Model):
    name = models.CharField(max_length=100)
    mascot = models.CharField(max_length=100, null=True, blank=True)
    master_school = models.ForeignKey(School)
    user = models.ForeignKey(settings.AUTH_USER_MODEL)

Поэтому я настроил форму для обработки редактирования пользовательской школы:

class UserSchoolForm(forms.ModelForm):
    class Meta:
        model = UserSchool
        fields = ['name','mascot']

А теперь у меня есть форма редакции:

class EditSchool(UpdateView):
    model = School
    success_url = reverse_lazy('list_schools')
    form_class = UserSchoolForm

    def get(self, request, *args, **kwargs):
        school = self.get_object()

        # make a copy of the school for this user
        user_school, created = UserSchool.objects.get_or_create(
            master_school=school, user=request.user,
            defaults={'name' : school.name, 'mascot' : school.mascot})

        self.object = user_school
        form = UserSchoolForm()
        context = self.get_context_data(form=form)
        return self.render_to_response(context)

Я знаю, что get () делает копию правильно, но когда отображается форма, в полях «Имя» или «по умолчанию» нет значений. Я подозреваю, что проблема заключается в том, что CLS.Model = школа, но Self.Object - это экземпляр пользовательской школы.

Я близко, но что -то упускаю? Я совершенно не на том пути? Есть ли лучшая модель для этого (например, наличие одного школьного экземпляра со специальным пользователем для "Master")?

(И одно небольшое осложнение-так как я старая рука в Джанго, но новые взгляды на основе класса, я пытаюсь использовать виды ванили, потому что мне легче выяснить, что происходит.)

Это было полезно?

Решение

Просто чтобы исключить очевидное - вы ничего не передаете конструктору формы. Вы пробовали это с instance=user_school? Там может быть больше, что нужно работать, но я бы начал там.

Чтобы немного расширить это - по вашему мнению, вы полностью переоцениваете встроенные get метод Это нормально, но это означает, что вы обходите часть автоматического поведения вашего Superclass. В частности, get метод ProcessFormView (один из ваших предков) создает форму, используя get_form Метод класса представления. FormMixin, другой предок, определяет get_form:

return form_class(**self.get_form_kwargs())

А также get_form_kwargs на ModelFormMixin добавляет self.object к форме kwargs:

kwargs.update({'instance': self.object})

Потому что ваш переопределенный get Метод не звонит get_form, это также не звонит get_form_kwargs и, следовательно, не проходит весь путь, который обеспечивает начальное связывание для формы.

Я лично попытался бы справиться с этим, изменив get_object Метод вашего пользовательского просмотра и оставить остальное в покое:

class EditSchool(UpdateView):
    model = School
    success_url = reverse_lazy('list_schools')
    form_class = UserSchoolForm

    def get_object(self, queryset=None):
        school = super(EditSchool, self).get_object(queryset=queryset)
        user_school, created = UserSchool.objects.get_or_create(
            master_school=school, user=self.request.user,
            defaults={'name' : school.name, 'mascot' : school.mascot})
        return user_school

Может быть больше изменений - я не проверял это - но оба get а также set Методы используют get_object, и свяжите его с формой в зависимости от необходимости.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top