Pergunta

Eu posso estar completamente fora da reserva aqui. (Sinta -se à vontade para me dizer se estou.)

Meu caso de uso é que tenho uma lista de escolas. O modelo da escola é bem simples:

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

Quando meu usuário deseja editar uma dessas escolas, não quero que eles editem a cópia mestre. Em vez disso, quero dar a eles sua própria cópia com a qual eles podem brincar. Quando terminarem a edição de sua cópia, podem enviar sua alteração e outra pessoa a aprovará. Então, eu tenho outra aula para a cópia do usuário da escola:

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)

Então, configurei um formulário para lidar com a edição da escola de usuários:

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

E agora eu tenho minha forma de escola de edição:

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)

Eu sei que o get () está fazendo a cópia corretamente, mas quando o formulário exibe, não há valores listados nos campos "nome" ou "padrão". Minha suspeita é que o problema esteja com o fato de que cls.model = escolar, mas o auto -objeto é uma instância do Usuário.

Estou perto, mas perdendo alguma coisa? Estou completamente no caminho errado? Existe um modelo melhor para isso (como ter uma única instância da escola com um usuário especial para "mestre")?

(E uma pequena complicação-já que sou uma mão velha no Django, mas novas visualizações baseadas em classe, estou tentando usar visualizações de baunilha porque acho mais fácil descobrir o que está acontecendo.)

Foi útil?

Solução

Só para descartar o óbvio - você não está passando nada para o construtor de formulários. Você já tentou com instance=user_school? Pode haver mais do que precisa de trabalho, mas eu começaria por aí.

Para expandir um pouco isso - na sua opinião, você está substituindo completamente o embutido get método. Tudo bem, mas significa que você está ignorando alguns dos comportamentos automatizados da sua superclasse. Especificamente, o get método de ProcessFormView (uma de suas classes ancestrais) instancia o formulário usando o get_form Método da classe de vista. FormMixin, outro ancestral define get_form:

return form_class(**self.get_form_kwargs())

E get_form_kwargs sobre ModelFormMixin adiciona self.object para o formulário kwargs:

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

Porque você está substituindo get Método não chama get_form, também não liga get_form_kwargs e, portanto, não passa por todo o caminho que fornece uma ligação inicial para o formulário.

Eu pessoalmente tentaria lidar com isso modificando o get_object Método de sua visualização personalizada e deixando o resto sozinho:

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

Pode haver mais mudanças necessárias - eu não testei isso - mas tanto o get e set Métodos usam get_object, e vinculá -lo ao formulário conforme apropriado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top