CreateView soll nach Vorauswahl Daten in Formularfelder laden

Django, Flask, Bottle, WSGI, CGI…
Antworten
gomez72
User
Beiträge: 71
Registriert: Sonntag 28. März 2021, 09:57

Hallo,
ich bin Python/Django Anfänger und erstelle eine kleine Webseite nach dem CRUD Modell. Es geht um Pflanzen, die in einer Datenbank angelegt werden können. Im Anschluss kann der User aus diesem Pflanzen Pool eine Pflanze wählen und in sein Beet einpflanzen/saen.
Es ist also eine Art persönlicher Saatkalender.

An einer Stelle bräuchte ich bitte Hilfe.
Es geht um eine spezielle CreateView Sache. Ein normales Formular mit leeren Feldern, die im Anschluss vom User ausgefüllt werden und die Daten in einer MySQL Datenbank gespeichert werden ist mir gelungen und die Technik ist mir jetzt geläufig. So habe ich das Anlegen von Pflanzen erstellt.

Jetzt möchte ich dem User die Möglichkeit geben diese Pflanzen tatsächlich zu säen und habe dafür folgende CreateView erstellt . Hierbei biete ich dem USer ein Formular an um die Saatdaten zu erfassen:

Code: Alles auswählen

class SeedCreate(LoginRequiredMixin, PermissionRequiredMixin,  CreateView):
    permission_required = 'seed.add_seedingprocess'
    model = SeedingProcess
    form_class = SeedForm
    template_name = 'seed/seed_create.html'
    success_url = reverse_lazy('seed:seed_list')

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super().form_valid(form)
Die dazugehörige ModelForm sieht so aus:

Code: Alles auswählen

class SeedForm(ModelForm):
    class Meta:
        model = SeedingProcess
        exclude = ('user', 'old_user_delete_in_future')
        labels = {

            'seeding_date':                     ('Saat Datum'),
            'confirm_seed':                     ('Saat bestätigt'),
            'planting_date':                    ('Auspflanz Datum'),
            'forecast_harvest':                 ('vorauss. Ernte'),
            'harvested_begin_date':             ('Ernte Begin'),
            'harvested_end_date':               ('Ernte Ende'),
            'fertilize_first_after_seeding':    ('Erstes Düngen'),
            'fertilize_interval':               ('Dünge Intervall'),
            'quantity_vegetables':              ('Anzahl Gemüse/Früchte'),
            'personal_records':                 ('persönliche Infos'),
            'plant':                            ('gesäte Pflanze')

        }


Das dazughörige Template für die form sieht so aus:

Code: Alles auswählen

{% extends 'main/base.html' %}

{% block content %}
<div class="container py-4">

    <div class="row py-3">
        <h2>Pflanze säen</h2>
    </div>

    <div class="row py-2">
        <div class="col-7">
        <form action="" method="post">
            {% csrf_token %}

              <table class="table table-striped table-hover table-bordered table-sm">
                {{ form.as_table}}
              </table>
            <a class="btn btn-danger btn-sm" href="{% url 'seed:seed_list' %}">Abbrechen</a>
            <button type="reset" class="btn btn-secondary btn-sm">Zurücksetzen</button>
            <button type="submit" class="btn btn-success btn-sm">Speichern</button>
        </form>
        </div>
    </div>

</div>
{% endblock content %}
Das dazugehörige Model sieht so aus:

Code: Alles auswählen

class SeedingProcess(models.Model):
    plant = models.ForeignKey(Plant, models.DO_NOTHING, db_column='plant', blank=True, null=True)
    seeding_date = models.DateField(blank=True, null=True)
    confirm_seed = models.IntegerField()
    planting_date = models.DateField(blank=True, null=True)
    forecast_harvest = models.DateField(blank=True, null=True)
    harvested_begin_date = models.DateField(blank=True, null=True)
    harvested_end_date = models.DateField(blank=True, null=True)
    fertilize_first_after_seeding = models.PositiveSmallIntegerField(blank=True, null=True)
    fertilize_interval = models.PositiveSmallIntegerField(blank=True, null=True)
    quantity_vegetables = models.PositiveIntegerField(blank=True, null=True)
    personal_records = models.CharField(max_length=500, blank=True, null=True)
#   old_user_delete_in_future = models.PositiveIntegerField(blank=True, null=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, default=2)

    def __str__(self):
        print_name = str(self.user) + " | " + str(self.plant)
        return print_name

    def get_absolute_url(self):
        return reverse('seed:seed_detail', args=[str(self.id)])

    class Meta:
        managed = True
        db_table = 'seeding_process'

Das Ergebnis sieht dann so aus
https://prnt.sc/b7SKdnyu8HbL

Der nächste Schritt ist, dass der User aus dem Dropdown eine Pflanze auswählen soll. Diese Pflanze ist in einer eigenen Pflanzen Tabelle gespeichert und soll letztendlich mit einer Fremdschlüsselbeziehung mit dem jetzt zu erstellenden Datensatz in der Saat Tabelle verbunden sein.

hier die Auswahl:
https://prnt.sc/6whbJBbbMkYu


und jetzt hätte ich gerne direkt nach dieser Pflanzenauswahl dass in bestimmten Felder aus der Pflanzentabelle default Werte geladen werden. Diese kann der User dann so lassen oder eben noch abändern und dann das Formular abschicken.

so sollte das aussehen:
https://prnt.sc/FAWLQr5FCxE2

Leider habe ich keine Erfahrung, ob in das Formular der CreateView default Werte aus einer andern Tabelle vorab hineingeladen werden können. Ich wäre für Hinweise und für eine Lösung sehr dankbar.

wünsche euch noch einen schönen Abend !
VG Gomez
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Du möchtest das im Formular ausfüllen lassen? Anhängig von der Auswahl?
Eine Möglichkeit die auf jeden Fall geht: das mit Javascript im Template unter zu bringen.
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

um das noch zu ergänzen: du musst immer daran denken, wo was läuft. Wenn das Template gerendert ist und an den Browser geschickt ist, die Django fertig, weil der Request-Response-Zyklus fertig ist. Die Auswahl im Dropdown Menü erfolgt rein im Browser, davon bekommt Django / der Server nichts mit. D.h. jegliche Interaktion dieser Art muss im Browser laufen => dann bitte du bei JavaScript.

Gruß, noisefloor
gomez72
User
Beiträge: 71
Registriert: Sonntag 28. März 2021, 09:57

noisefloor hat geschrieben: Freitag 4. März 2022, 14:51 D.h. jegliche Interaktion dieser Art muss im Browser laufen => dann bitte du bei JavaScript.
Gruß, noisefloor
ok verstehe, ich werde mir wohl JavaScript dann noch draufpacken müssen. Um das Projekt jetzt aber nicht auszubremsen würde mir auch ein Workaround einfallen. Erst die Pflanze auswählen - das dann an de Server zurückschicken und ein vorausgefülltes Formular zurück bekommen. Das müsste doch mit Djanog so funktionieren können. Habe nur leider nicht die Ahnung , wie ?!
VG Gomez
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

ja, ginge auch. Du hast halt den X Request - Response Roundtrips über den Server. Wenn man wenig Trafic erwartet geht das. Aber es ist IMHO vergleichsweise aufwendig, weil du entsprechend viele Views schreiben musst bzw. die Views komplexer werden.

Wenn du das mit der Webentwicklung weiter machen willst schadet es aber auf keinen Fall, sich mal ein bisschen mit JavaScript zu beschäftigen. Da kommst du irgendwann nicht drumherum. Zumindest nicht um so einfache Sachen wie auf die Änderung in einem Eingabefeld reagieren und dann woanders was einzutragen. Das ist mit ein paar Zeilen JavaScript machbar.

Gruß, noisefloor
gomez72
User
Beiträge: 71
Registriert: Sonntag 28. März 2021, 09:57

ok verstanden. aber eins schnackelt noch nicht. ich arbeite mit JavaScript komplett im Browser, ok. Sprich es gehen keine Anfragen dann an den Server bzw an die Datenbank mehr. das würde aber auch bedeuten, dass ich die komplette Datenbank Tabelle mitschicken muss, damit JavaScript dann den richtigen Datensatz auswählen kann. ist das bei großen Tabellen nicht auch ein elendiger overhead - dann ?
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

kommt drauf an. Wenn es wirklich viele Daten sind würde man eher die Daten für die Webseite per JavaScript fetch-API vom Server dynamisch nachladen. Klingt vielleicht kompliziert, ist es aber nicht. Das ist auch mit ein paar Zeilen JS erledigt. Plus du brauchst halt noch die passende Route und den passenden View, wo die Daten gezogen werden.

Gruß, noisefloor
gomez72
User
Beiträge: 71
Registriert: Sonntag 28. März 2021, 09:57

ok vielen Dank. Da muss ich glaube ich noch viel lernen. Habe es aber soweit global Verstanden wo die Reise hingeht. Ich denke Codebeispiele wirst du nicht parat haben oder, wo genau dieses abgebildet wird ?
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

die JavaScript fetch-API sehr gängig, da findest du einen Haufen Code und Tutortials zu, z.B. bei MDN.

Wenn du JavaScript noch nie genutzt hast würde ich das ggf. Schritt für Schritt aufbauen: du reduzierst zum Testen die Anzahl der Pflanzen auf eine paar (3 oder 4) und sendest du Daten komplett an den Browser mit. Dann implementierst du, dass die Daten in Abhängigkeit von der Auswahl angezeigt werden. Den Inhalt von HTML-Elementen ersetzen ist ziemlich Basic, da findest du haufenweise Beispiele zu. Wenn das klappt sendest du die Daten im nächsten Schritt nicht mehr mit, sondern ziehst sie via fetch.

Gruß, noisefloor
gomez72
User
Beiträge: 71
Registriert: Sonntag 28. März 2021, 09:57

noisefloor hat geschrieben: Freitag 4. März 2022, 20:43 Hallo,

die JavaScript fetch-API sehr gängig, da findest du einen Haufen Code und Tutortials zu, z.B. bei MDN.

Wenn du JavaScript noch nie genutzt hast würde ich das ggf. Schritt für Schritt aufbauen: du reduzierst zum Testen die Anzahl der Pflanzen auf eine paar (3 oder 4) und sendest du Daten komplett an den Browser mit. Dann implementierst du, dass die Daten in Abhängigkeit von der Auswahl angezeigt werden. Den Inhalt von HTML-Elementen ersetzen ist ziemlich Basic, da findest du haufenweise Beispiele zu. Wenn das klappt sendest du die Daten im nächsten Schritt nicht mehr mit, sondern ziehst sie via fetch.

Gruß, noisefloor

danke das hört sich gut an, das schaue ich mir an.
Antworten