Pregunta

Puedo estar completamente fuera de la reserva aquí. (No dudes en decirme si lo soy).

Mi caso de uso es que tengo una lista de escuelas. El modelo de la escuela es bastante simple:

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

Cuando mi usuario quiere editar una de estas escuelas, no quiero que editen la copia maestra. En cambio, quiero darles su propia copia con la que puedan jugar. Cuando hayan terminado de editar su copia, pueden enviar su cambio, y alguien más lo aprobará. Así que tengo otra clase para la copia del usuario de la escuela:

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)

Así que configuré un formulario para manejar la edición de UserSchool:

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

Y ahora tengo mi forma de educación edits:

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)

Sé que Get () está haciendo la copia correctamente, pero cuando se muestra el formulario, no hay valores enumerados en los campos "Nombre" o "Valor predeterminado". Mi sospecha es que el problema es con el hecho de que Cls.Model = School, pero Self.Object es una instancia de UserSchool.

¿Estoy cerca pero me falta algo? ¿Estoy completamente en el camino equivocado? ¿Hay un mejor modelo para esto (como tener una sola instancia escolar con un usuario especial para "maestro")?

(Y una pequeña complicación: dado que soy una vieja mano en Django, pero nuevas vistas basadas en la clase, estoy tratando de usar vistas de vainilla porque me resulta más fácil descubrir qué está sucediendo).

¿Fue útil?

Solución

Solo para descartar lo obvio: no estás pasando nada al constructor de formulario. Lo has probado con instance=user_school? Puede haber más que necesite trabajo, pero comenzaría allí.

Para ampliar esto un poco: en su opinión, está anulando por completo el incorporado get método. Está bien, pero significa que está pasando por alto parte del comportamiento automatizado de su superclase de visión. Específicamente, el get método de ProcessFormView (una de sus clases de antepasados) Instancia la forma utilizando el get_form Método de la clase View. FormMixin, otro antepasado, define get_form:

return form_class(**self.get_form_kwargs())

Y get_form_kwargs en ModelFormMixin agrega self.object a la forma kwargs:

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

Porque tu anulación get El método no llama get_form, tampoco llama get_form_kwargs y, por lo tanto, no pasa por toda la ruta que proporcione una unión inicial para la forma.

Personalmente intentaría manejar esto modificando el get_object Método de su vista personalizada y dejar el resto solo:

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

Puede que se necesiten más cambios, no he probado esto, pero ambos get y set Los métodos usan get_object, y unirlo a la forma según corresponda.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top