[python] Django: mehrere Modelle in einer Vorlage unter Verwendung von Formularen


2 Answers

Ich war gerade in der gleichen Situation vor einem Tag, und hier sind meine 2 Cent:

1) Ich fand wohl die kürzeste und prägnanteste Demonstration des multiplen Modelleintrags in Einzelform: http://collingrady.wordpress.com/2008/02/18/editing-multiple-objects-in-django-with-newforms/ .

Kurz zusammengefasst: Erstellen Sie für jedes Modell ein Formular, senden Sie beide Vorlagen in einem einzigen <form> -Format mit dem prefix keyarg und lassen Sie die View-Handle-Validierung durchführen. Wenn es eine Abhängigkeit gibt, stellen Sie sicher, dass Sie das "Eltern" -Modell vor der Abhängigkeit speichern und die ID der Eltern für den Fremdschlüssel verwenden, bevor Sie das Speichern des "Kind" -Modells veranlassen. Der Link hat die Demo.

2) Vielleicht können Formsets dafür eingesetzt werden, aber so weit ich mich eingehender geäußert habe, sind Formsets in erster Linie für die Eingabe von Vielfachen des gleichen Modells gedacht, das optional durch Fremdschlüssel mit einem anderen Modell / anderen Modellen verknüpft werden kann . Es scheint jedoch keine Standardoption für die Eingabe von mehr als einem Modell Daten zu geben, und das ist nicht das, was Formset zu sein scheint.

Question

Ich erstelle eine Support-Ticket-Tracking-App und habe ein paar Modelle, die ich von einer Seite erstellen möchte. Tickets gehören einem Kunden über einen ForeignKey. Notizen gehören auch zu Tickets über ForeignKey. Ich möchte die Möglichkeit haben, einen Kunden auszuwählen (das ist ein ganz separates Projekt) ODER einen neuen Kunden zu erstellen, dann ein Ticket zu erstellen und schließlich eine Notiz zu erstellen, die dem neuen Ticket zugewiesen wird.

Da ich ziemlich neu in Django bin, tendiere ich dazu, iterativ zu arbeiten und jedes Mal neue Funktionen auszuprobieren. Ich habe mit ModelForms gespielt, möchte aber einige Felder ausblenden und eine komplexe Validierung durchführen. Es scheint so, als ob das Maß an Kontrolle, das ich suche, Formsets erfordert oder alles von Hand erledigt, komplett mit einer mühsamen, handcodierten Templateseite, die ich vermeiden möchte.

Gibt es eine schöne Eigenschaft, die ich vermisse? Hat jemand eine gute Referenz oder ein Beispiel für die Verwendung von Formsets? Ich verbrachte ein ganzes Wochenende mit den API-Dokumenten für sie und ich bin immer noch ahnungslos. Ist es ein Designproblem, wenn ich alles kaputt mache und handkodiert habe?




"Ich möchte einige der Felder verstecken und eine komplexe Validierung durchführen."

Ich beginne mit der integrierten Admin-Oberfläche.

  1. Erstellen Sie das ModelForm, um die gewünschten Felder anzuzeigen.

  2. Erweitern Sie das Formular mit den Validierungsregeln innerhalb des Formulars. Normalerweise ist dies eine clean Methode.

    Stellen Sie sicher, dass dieser Teil einigermaßen gut funktioniert.

Sobald dies erledigt ist, können Sie sich von der integrierten Admin-Oberfläche entfernen.

Dann können Sie mit mehreren, teilweise verwandten Formularen auf einer einzigen Webseite herumspielen. Dies ist eine Sammlung von Vorlagen, um alle Formulare auf einer Seite zu präsentieren.

Dann müssen Sie die View-Funktion schreiben, um die verschiedenen Form-Dinge zu lesen und zu validieren und die verschiedenen Objekt-Saves () auszuführen.

"Ist es ein Design-Problem, wenn ich alles kaputt mache und alles handkodiert habe?" Nein, es ist nur eine Menge Zeit für wenig Nutzen.




Das MultiModelForm von django-betterforms ist ein praktischer Wrapper, um das zu tun, was in Gnudiffs Antwort beschrieben wird . Es ModelForm reguläre ModelForm in einer einzigen Klasse ein, die transparent (zumindest für die grundlegende Verwendung) als einzelnes Formular verwendet wird. Ich habe unten ein Beispiel aus ihren Dokumenten kopiert.

# forms.py
from django import forms
from django.contrib.auth import get_user_model
from betterforms.multiform import MultiModelForm
from .models import UserProfile

User = get_user_model()

class UserEditForm(forms.ModelForm):
    class Meta:
        fields = ('email',)

class UserProfileForm(forms.ModelForm):
    class Meta:
        fields = ('favorite_color',)

class UserEditMultiForm(MultiModelForm):
    form_classes = {
        'user': UserEditForm,
        'profile': UserProfileForm,
    }

# views.py
from django.views.generic import UpdateView
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import redirect
from django.contrib.auth import get_user_model
from .forms import UserEditMultiForm

User = get_user_model()

class UserSignupView(UpdateView):
    model = User
    form_class = UserEditMultiForm
    success_url = reverse_lazy('home')

    def get_form_kwargs(self):
        kwargs = super(UserSignupView, self).get_form_kwargs()
        kwargs.update(instance={
            'user': self.object,
            'profile': self.object.profile,
        })
        return kwargs



Related