Frage

Ich kann hier vollständig vor der Reservierung sein. (Fühlen Sie sich frei zu sagen, ob ich es bin.)

Mein Anwendungsfall ist, dass ich eine Liste von Schulen habe. Das Schulmodell ist ziemlich einfach:

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

Wenn mein Benutzer eine dieser Schulen bearbeiten möchte, möchte ich nicht, dass er die Master -Kopie bearbeitet. Stattdessen möchte ich ihnen ihre eigene Kopie geben, mit der sie spielen können. Wenn sie fertig sind, um ihre Kopie zu bearbeiten, können sie ihre Änderung einreichen, und jemand anderes wird es genehmigen. Ich habe also eine andere Klasse für die Kopie des Benutzers der Schule:

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)

Also habe ich ein Formular eingerichtet, um die Bearbeitung der UserSchool zu bearbeiten:

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

Und jetzt habe ich meine Editschool -Form:

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)

Ich weiß, dass Get () die Kopie korrekt erstellt, aber wenn das Formular angezeigt wird, sind in den Feldern "Name" oder "Standard" keine Werte aufgeführt. Mein Verdacht ist, dass das Problem mit der Tatsache besteht, dass Cls.model = Schule, aber Self.Object eine Instanz der UserSchool ist.

Bin ich nah, aber ich fehlt etwas? Bin ich völlig auf dem falschen Weg? Gibt es dafür ein besseres Modell (wie eine einzige Schulinstanz mit einem speziellen Benutzer für "Master")?

(Und eine kleine Komplikation-Da ich bei Django eine alte Hand bin, aber neue klassenbasierte Ansichten, versuche ich, Vanilleansichten zu verwenden, weil ich es einfacher finde, herauszufinden, was los ist.)

War es hilfreich?

Lösung

Nur um das Offensichtliche auszuschließen - Sie geben nichts an den Formularkonstruktor. Hast du es mit damit versucht mit instance=user_school? Es mag mehr geben, das Arbeit braucht, aber ich würde dort anfangen.

Um dies ein wenig zu erweitern - in Ihrer Ansicht überschreiben Sie das eingebaute in die Einbau. get Methode. Das ist in Ordnung, aber es bedeutet, dass Sie einige der automatisierten Verhaltensweisen Ihrer Sichtweise Superclass umgehen. Insbesondere die get Methode von ProcessFormView (Eine Ihrer Vorfahren) instanziiert die Form mit dem Form get_form Methode der View -Klasse. FormMixin, ein anderer Vorfahr, definiert get_form:

return form_class(**self.get_form_kwargs())

Und get_form_kwargs an ModelFormMixin fügt hinzu self.object zur Form des Formulars kwargs:

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

Weil du überschrieben bist get Methode wird nicht aufgerufen get_form, Es ruft auch nicht an get_form_kwargs und geht daher nicht den gesamten Weg durch, der eine anfängliche Bindung für das Formular liefert.

Ich persönlich würde versuchen, dies zu behandeln, indem ich das ändern würde get_object Methode Ihrer benutzerdefinierten Ansicht und lassen Sie den Rest in Ruhe:

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

Möglicherweise werden mehr Änderungen benötigt - ich habe das nicht getestet - aber beide get und set Methoden verwenden get_object, und binden Sie es gegebenenfalls an die Form.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top