Von Flask zu Django -> Wert an Webseite zurück geben

Django, Flask, Bottle, WSGI, CGI…
Antworten
Benutzeravatar
Dennis89
User
Beiträge: 1638
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo zusammen,

bis jetzt hatte ich immer `Flask` genutzt und da ich aktuell eine neue Web-Anwendung entwickle, dachte ich, das wäre ein guter Zeitpunkt `Django` zu verwenden. Allerdings habe ich zwei Probleme. Damit die Seite dynamisch ist, will ich wieder `Vue` verwenden.
Meine Index.html sieht so aus:

Code: Alles auswählen

<html lang="de">
<head>
  <meta name="viewport" content="width=device-width,initial-scale=1.0" charset="utf-8">
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <title>Betriebsstunden-Auswertung</title>
</head>

<body>
  <div id="app">
      <form method="post">
        {% csrf_token %}
        {{ date_range.as_p }}
        {{ pressure_range.as_p }}

        <button @click="get_operation_hours">Auswertung</button>
      </form>
      {{ operationHours }}blaaaaaa
  </div>

<script>
  const { createApp, ref } = Vue

  createApp({
    setup() {
      let operationHours = ref(99999999)

    async function get_operation_hours() {
        const response = await fetch('http://localhost:8000/evaluation');
        operationHours.value = await response.json();
      }

  return { operationHours, get_operation_hours }
  }
  }).mount('#app')
</script>
</body>
</html>
Erstes Problem, das ich gar nicht verstehe. Wieso wird meine `operationHours` von 999999 nicht angezeigt, wenn ich die Seite lade? `blaaaaaa` wird angezeigt und in der Browser-Konsole kommt keine Fehlermeldung.

Wie man sieht, will ich anhand der Eingaben, aus einer Datenbank Betriebsstunden aussuchen und diese zurück geben. Dafür habe ich folgende `views.py`:

Code: Alles auswählen

from django.http import JsonResponse
from django.shortcuts import render

from .forms import DateRange, PressureRange


def index(request):
    if request.method == "POST":
        date_range = DateRange(request.POST)
        pressure_range = PressureRange(request.POST)
        if date_range.is_valid() and pressure_range.is_valid():
            date_range = (
                date_range.cleaned_data["start"],
                date_range.cleaned_data["end"],
            )
            pressure_range = {
                "min": pressure_range.cleaned_data["min"],
                "max": pressure_range.cleaned_data["max"],
            }
            # operation_hours = get_operation_hours(date_range, pressure_range)
            operating_hours = 385
            return JsonResponse({"operating_hours": operating_hours})
    else:
        date_range = DateRange()
        pressure_range = PressureRange()
    return render(
        request,
        "evaluation/index.html",
        context={"date_range": date_range, "pressure_range": pressure_range},
    )
Zum testen, gebe ich einfach mal 385 zurück. Wenn ich den Button auf der Webseite klicke, dann öffnet sich eine "schwarze" Seite mit dem Inhalt, den ich als JSON geschickt habe. Ihr wisst bestimmt was ich meine, die Seite hat Reiter: "JSON", "Rohdaten" und "Kopfzeilen".
Mit Flask hätte ich nur das Wörterbuch zurück geschickt und hätte dass dann im JavaScript-Teil erhalten. Hier läuft das irgendwie anders.
Im Django-Tutorial wird `HttpResponse` verwendet, ich will allerdings den Wert auf der aktuellen Seite anzeigen und keine andere Seite.

Und was ich grundsätzlich noch nicht verstanden habe. Ich kann den Button auch mit

Code: Alles auswählen

<input type="submit" value="Drück mich">
erstellen und `index` wird trotzdem ausgeführt. Ich kenne das halt von `Flask` so, das ich immer die Route angeben muss. Woher weiß der Button wo's lang geht?

Achja, `Flask` bringt alles mit, was es für die Anwendung benötigt. Allerdings, wenn die Zeit reicht, dann wird die Anwendung immer erweitert und es soll dann für bestimmte Bereiche, abhängig vom Benutzer, Zugänge verweigert werden. Daher will ich gleich mit `Django` starten.

Danke und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Sirius3
User
Beiträge: 18337
Registriert: Sonntag 21. Oktober 2012, 17:20

Du mußt Dich entscheiden, ob Du nun Django zum Rendern verwenden möchtest, oder VUE. Du läßt django rendern und wunderst Dich, dass dann keine Variablen mehr durch vue erkannt werden.
Was mich wundert ist, dass Dein fetch GET zu einer json Rückgabe führt. Du scheinst doch ein form-submit abzusetzen, was natürlich die aktuelle Seite ersetzt.
Mach eine klare Trennung: ein http-Endpunkt sollte nicht sowohl html als auch json zurückliefen. Bei Formularen on-submit abfangen, damit das keine neu Seite lädt und alles mit javascript abarbeiten.
Benutzeravatar
sparrow
User
Beiträge: 4601
Registriert: Freitag 17. April 2009, 10:28

@Dennis89: Und der obligatorische Hinweis, der einem nicht immer gleich klar ist: Django kommt mit sehr viel, aber man muss nicht alles verwenden.
Django + Django Rest Framework eignet sich hervorragend um einfach REST APIs zu bauen, weil das DRF direkt an Djangos ORM dockt. Und Djangos Render/Template-Engine müsstest du gar nicht verwenden, wenn im Frontend so etwas wie Vue oder React läuft.
Benutzeravatar
Dennis89
User
Beiträge: 1638
Registriert: Freitag 11. Dezember 2020, 15:13

Danke für die Hinweise.
Ja das macht natürlich Sinn. Ich würde dann Vue für das redern verwenden, weil ich denke so habe ich die Logik und das Aussehen besser von einander getrennt und könnte auch schneller von `Django` auf was anderes wechseln oder von Vue auf was anderes.

Kann von euch bitte mal jemand dieses Beispiel testen?
https://vcalendar.io/getting-started/in ... e-from-cdn

Ich habe das 1:1 kopiert, in eine extra Datei unter `/var/www/html/` abgelegt und lasses es über `httpd` unter Fedora ausliefern. Es erscheint eine leere Seite und die Browser-Konsole sagt mir folgendes:

Code: Alles auswählen

Uncaught TypeError: a.a.mixin is not a function
    1315 			https://unpkg.com/v-calendar:1			v-calendar:1:10238
    r 				https://unpkg.com/v-calendar:1
    2af9 			https://unpkg.com/v-calendar:1
    r 				https://unpkg.com/v-calendar:1
    34e9 			https://unpkg.com/v-calendar:1
    34e9 			https://unpkg.com/v-calendar:1
    r 				https://unpkg.com/v-calendar:1
    fb15 			https://unpkg.com/v-calendar:1
    r 				https://unpkg.com/v-calendar:1
    <anonymous> https://unpkg.com/v-calendar:1
    <anonymous> https://unpkg.com/v-calendar:1
    <anonymous> https://unpkg.com/v-calendar:1
    <anonymous> https://unpkg.com/v-calendar:1

[Vue warn]: Failed to resolve component: vdatepicker			vue.global.js:2348:15
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <App> 
[Vue warn]: Failed to resolve component: vcalendar			vue.global.js:2348:15
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <App> 
Weil ich nicht wirklich was einrichten muss, würde ich gerne CDN benutzen.

Danke und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
Dennis89
User
Beiträge: 1638
Registriert: Freitag 11. Dezember 2020, 15:13

Hm, das ist wohl bekannt, aber es wird nichts unternommen:
https://github.com/nathanreyes/v-calendar/issues/1511
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
noisefloor
User
Beiträge: 4263
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Alternativ zum Django REST Framework geht auch Django Ninja. Das ist von FastAPI inspiriert. Was man am Ende nimmt ist in Teilen Geschmackssache.

Jedenfalls sind beide relativ verbreitet, Django REST Framework gibt es (deutlich) länger. Aber für beide sollte man viele Infos im Netz (SO usw.) finden.

Gruß, noisefloor
Benutzeravatar
Dennis89
User
Beiträge: 1638
Registriert: Freitag 11. Dezember 2020, 15:13

Danke, schaue ich mir auch mal an.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
nezzcarth
User
Beiträge: 1794
Registriert: Samstag 16. April 2011, 12:47

Nebenbemerkung: Eingebettetes JavaScript im HTML wie in deinem Eingangsspost sollte man nach Möglichkeit vermeiden, zumindest wenn man perspektivisch vorhat CSP umzusetzen (was man in Erwägung ziehen sollte). Es ist erfahrungsgemäß leichter, das gleich mit zu bedenken, als es später mühselig nachzuarbeiten.
Antworten