Dies ist eine Fortsetzung von diesem Artikel. Eine "projektähnliche Einheit" ist ein "Projekt" in einem Task-Management-Tool usw. Da das Theater verwaltet wird, entspricht die "Performance" diesem.
---> GitHub Repository (Python 3.8.1, Django 3.0.3)
Letztes Mal haben wir "Performances" und "Performance User" erstellt und den Zugriff kontrolliert. Wir haben es auch "Benutzern einer Aufführung" ermöglicht, Daten (Akteure) hinzuzufügen, die zu dieser Aufführung gehören.
Dieses Mal möchte ich über die Schnittstelle zum Hinzufügen und Bearbeiten von Daten nachdenken, die zur Aufführung gehören.
Wenn Sie beispielsweise in den Daten "Charaktere" ein Feld "ForeignKey" mit dem Namen "Casting" erstellen und auf "Schauspieler" verweisen, möchten Sie nur die Schauspieler für diese Aufführung auswählen können. Durch einfaches Erstellen von "Model" und "View" wie unten gezeigt können jedoch alle Schauspieler (einschließlich Schauspieler, die zu anderen Performances gehören) als "Cast" ausgewählt werden.
models.py
from django.db import models
class Character(models.Model):
'''Charakter
'''
production = models.ForeignKey(Production, verbose_name='Performance',
on_delete=models.CASCADE)
name = models.CharField('Rollenname', max_length=50)
cast = models.ForeignKey(Actor, verbose_name='Casting',
on_delete=models.SET_NULL, blank=True, null=True)
views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.edit import CreateView
from .models import Character
class ChrCreate(LoginRequiredMixin, CreateView):
'''Zusätzliche Ansicht des Charakters
'''
model = Character
fields = ('name', 'cast')
▲ Sie können die Schauspieler anderer Aufführungen auswählen.
Erwägen Sie, einer "Aufführung" einen "Charakter" hinzuzufügen. "Charaktere" hat ein Feld namens "Casting" und "beziehen sich auf" Akteursdaten ", die zur Aufführung gehören".
Die obige Abbildung ist "ein Beispiel, bei dem die Schauspieler anderer Aufführungen wählen können", aber mit Ausnahme dieses Problems ist die Benutzeroberfläche in Ordnung.
In Anbetracht der Tatsache, dass die vom Webbrowser gesendete Anfrage möglicherweise manipuliert wurde, sollten nicht nur die UI-Optionen, sondern auch der "akzeptierte Wert" auf "nur den Akteur der Leistung" beschränkt werden.
Überlegen Sie, wann Sie die hinzugefügten "Zeichen" später bearbeiten möchten. Es wäre das ursprüngliche Mokuami, wenn die Zugehörigkeit (Performance) des Charakters, der den "Schauspieler der Performance" besetzt, geändert werden könnte. Es scheint gut zu sein, es unmöglich zu machen, die Zugehörigkeit des einmal geschaffenen "Charakters" zu ändern.
Diese App verwendet eine klassenbasierte Ansicht (CreateView
), sodass das Formular automatisch generiert wird und Sie die Vorlage wie folgt schreiben können:
modelname_form.html
<form method="post">
{% csrf_token %}
<table>
{{ form }}
</table>
{% if object %}
<input type="submit" value="aktualisieren">
{% else %}
<input type="submit" value="hinzufügen">
{% endif %}
</form>
Die Eingabe-Benutzeroberfläche für jedes Feld des Objekts wird in diesem Teil mit dem Namen "{{form}}" erweitert, sodass Sie es auch hier neu schreiben können. In diesem Fall müssen Sie die Auswahl "Besetzung" als "Kontext" übergeben und auch die Art und Weise, wie das Formular in die Vorlage geschrieben wird, für jedes Feld trennen.
Hier werden wir es stoppen und den Inhalt des Formulars, das im Teil {{form}} `erweitert wurde, im Voraus ändern.
Eine Möglichkeit, den Inhalt eines Formulars zu ändern, besteht darin, eine Unterklasse des Formulars zu erstellen. Sie können diese jedoch auch ändern, ohne dies zu tun. Hier werden wir es in der Methode der Ansicht ändern. Wir werden später über Unterklassenformulare sprechen.
Ein Formular ist eine Art von "Kontext", der von einer Ansicht an eine Vorlage übergeben wird. Sie können also "get_context_data ()" überschreiben und wie folgt ändern: Die "ProdBaseCreateView", die die Ansicht im folgenden Code erbt, ist eine abstrakte Klasse, die die Leistungs-ID empfängt und den Zugriff steuert (siehe Vorheriger Artikel. Bitte sehen Sie. Sie müssen sich jetzt nicht zu viele Sorgen machen.
rehearsal/views/views.py
class ChrCreate(ProdBaseCreateView):
'''Zusätzliche Ansicht des Charakters
'''
model = Character
fields = ('name', 'cast')
def get_context_data(self, **kwargs):
'''Ändern Sie die an die Vorlage übergebenen Parameter
'''
context = super().get_context_data(**kwargs)
#Zeigen Sie nur die Schauspieler der Aufführung
actors = Actor.objects.filter(production=self.production)
#Erstellen Sie eine Auswahl
choices = [('', '---------')]
choices.extend([(a.id, str(a)) for a in actors])
#In Form setzen
context['form'].fields['cast'].choices = choices
return context
--context ['form']
ermöglicht es Ihnen, das Formular anzuzeigen, das die Ansicht an die Vorlage übergeben möchte.
▲ Es wurden nur die Akteure der Aufführung angezeigt, zu denen die Charaktere gehören.
Ich sehe Informationen, dass das Festlegen von "Auswahlmöglichkeiten" in einem Feld in einem Formular automatisch andere Werte abstößt, aber als ich es tatsächlich ausprobiert habe, war dies nicht der Fall. Es kann sein, dass das Feld mit "Auswahl" "ForeignKey" war.
▲ Versuchen Sie, die Optionen in Ihrem Browser zu manipulieren.
▲ Der manipulierte Wert wurde hinzugefügt.
Sie können die Methoden der Ansicht überschreiben, um die Validierungsergebnisse zu ändern. Am Ende ist es sauberer, eine Unterklasse des Formulars zu erstellen, aber zuerst machen wir es nur mit der Ansicht.
rehearsal/views/views.py
class ChrCreate(ProdBaseCreateView):
# (Unterlassung)
def form_valid(self, form):
'''Nach bestandener Validierung
'''
#Die Validierung ist fehlgeschlagen, wenn die Besetzung nicht der Akteur derselben Leistung ist
instance = form.save(commit=False)
if instance.cast.production != self.production:
return self.form_invalid(form)
return super().form_valid(form)
form_valid ()
ist eine ansichtsseitige Verarbeitungsmethode, die aufgerufen wird, wenn das Formular die Validierung besteht.
Wenn Sie die Methode (form_invalid ()
) zwangsweise aufrufen, die aufgerufen wird, wenn die Validierung nicht bestanden wird, können Sie das Speichern verhindern.
--form.save (commit = False)
ruft das Objekt ab, das das Formular speichern möchte. Wenn Sie commit = True
setzen, wird es gespeichert und dann abgerufen.
self.production
in der if
-Anweisung ist ein Attribut der Oberklasse ProdBaseCreateView
dieser Ansicht, die die" Leistung "des Objekts aufweist, das Sie speichern möchten (siehe [Weitere Informationen]. Bitte lesen Sie den vorherigen Artikel](https://qiita.com/satamame/items/959e21ade18c48e1b4d6).Es kann unangenehm sein, form_invalid ()
von form_valid ()
wie oben aufzurufen.
Wenn Sie sich die Bedeutung von "form_valid ()" als "den Ort vorstellen, an dem Sie aufgerufen werden, wenn Sie die Validierung bestehen und die Verarbeitung fortsetzen", liegt dies daran, dass ein Gefühl der Inkongruenz wie ein Akt der Überrechterung besteht.
Infolgedessen wird "form_invalid ()" aufgerufen, und es scheint, dass eine solche Chabudai-Rückgabe zulässig ist.
Im schlimmsten Fall können Sie form_valid ()
erlauben, auch form_valid ()
aufzurufen, was zu einem zirkulären Aufruf führt.
Wenn Sie die Regeln festlegen, z. B. die Einbahnstraße, gibt es natürlich kein Problem mit der oben genannten Methode.
Wenn Sie das Formular in Unterklassen unterteilen möchten, müssen Sie nicht einmal die get_context_data () überschreiben, die Sie unter "Ändern der Benutzeroberfläche" erstellt haben. Stattdessen überschreibt die Ansicht eine Methode namens "get_form_kwargs ()". Es ist ein Bild, das das generierte Formular selbst anpasst, anstatt das "an die Vorlage übergebene Formular" zu ändern.
Der Rückgabewert, der mit get_form_kwargs () abgerufen werden kann, ist ein Wörterbuch mit Schlüsselwortargumenten, die an den Formularkonstruktor übergeben werden. Wenn Sie diesem also einen Eintrag hinzufügen, können Sie ihn auf der Formularseite verwenden.
Das Folgende ist ein Beispiel für das Überschreiben von "get_form_kwargs ()" unter der Annahme, dass eine Klasse namens "ChrForm" definiert ist. Wenn Sie in der Ansicht "form_class" setzen, setzen Sie keine "Felder" (ich denke, dies hätte zu einem Fehler geführt).
rehearsal/views/views.py
from rehearsal.forms import ChrForm
class ChrCreate(ProdBaseCreateView):
'''Zusätzliche Ansicht des Charakters
'''
model = Character
form_class = ChrForm
def get_form_kwargs(self):
'''Ändern Sie die an das Formular übergebenen Informationen
'''
kwargs = super().get_form_kwargs()
#Bestehen Sie die Produktion, da sie zur Validierung auf der Formularseite verwendet wird
kwargs['production'] = self.production
return kwargs
rehearsal/forms.py
from django import forms
from production.models import Production
from .models Character
class ChrForm(forms.ModelForm):
'''Formular zum Hinzufügen / Aktualisieren von Zeichen
'''
class Meta:
model = Character
fields = ('name', 'cast')
def __init__(self, *args, **kwargs):
#Extrahieren Sie die in der Ansicht hinzugefügten Parameter
production = kwargs.pop('production')
super().__init__(*args, **kwargs)
#Das Casting kann nur von Schauspielern derselben Aufführung ausgewählt werden
queryset = Actor.objects.filter(production=production)
self.fields['cast'].queryset = queryset
Sie setzen "Queryset" anstelle von "Auswahl" im Feld "Besetzung". Auf diese Weise können Sie Auswahlmöglichkeiten basierend auf dem von Ihnen festgelegten Abfragesatz generieren und validieren.
Wenn Sie dieses Formular erstellen, können Sie es nicht nur für die zusätzliche Ansicht, sondern auch für die Aktualisierungsansicht verwenden.
Lassen Sie uns nun die Optionen manipulieren, die wir in "Validierung" vorgenommen haben.
Verbieten Sie Änderungen an "Produktion" in diesen Add / Update-Ansichten, damit Sie die "Leistung" der "Charaktere" oder "Schauspieler" nicht ändern können.
Wenn Sie normalerweise in Django ein Formular mit "Modell" erstellen, können alle Felder bearbeitet werden. Sie müssen daher die bearbeitbaren Felder angeben.
Möglicherweise möchten Sie auch auf Felder verweisen, die Sie nicht aus Formularen oder Vorlagen bearbeiten. In beiden Fällen können Sie, wie bereits erwähnt, die Ansichten "get_context_data ()" und "get_form_kwargs ()" verwenden.
Recommended Posts