ich bin gerade dabei ein Django Projekt mithilfe eines Tutorials umzusetzen und komme nun leider nicht mehr weiter. Der Fehler tritt erstmalig auf, wenn ich json.loads benutzte. Ich vermute das so ein Fehler unter anderem auftritt, wenn z.b aus einer HTML-Datei die falsche ID übergibt oder aber wenn das JSON Format ungültig ist.
Beides habe ich bei mir kontrolliert und keinen Fehler bzw. Syntaxfehler gefunden.
Im Browser wird mir zudem noch dieser Fehler anzeigt:
Uncaught TypeError: Cannot read properties of null (reading 'value')
at warenkorb.js
Hier ist der Code aus den verschiedenen Datein:
views.py:
Code: Alles auswählen
from django.shortcuts import render, redirect
from django.contrib import messages
from . models import *
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json
from django.contrib.auth import authenticate, login, logout
# from django.contrib.auth.forms import UserCreationForm da wird nun ein eignes usercreation from benutzen brauchen wir das Standardformular nicht mehr
from . forms import EigeneUserCreationForm
import uuid # für eine eindeutige id
def shop(request):
artikels = Artikel.objects.all()
ctx = {'artikels':artikels}
return render(request, 'shop/shop.html', ctx)
def warenkorb(request):
if request.user.is_authenticated:
kunde = request.user.kunde
bestellung, created = Bestellung.objects.get_or_create(kunde=kunde, erledigt=False)
artikels = bestellung.bestellteartikel_set.all()
else:
artikels = []
bestellung = []
ctx = {'artikels':artikels, 'bestellung':bestellung}
return render(request, 'shop/warenkorb.html', ctx)
def kasse(request):
if request.user.is_authenticated:
kunde = request.user.kunde
bestellung, created = Bestellung.objects.get_or_create(kunde=kunde, erledigt=False)
artikels = bestellung.bestellteartikel_set.all()
else:
artikels = []
bestellung = []
ctx = {'artikels':artikels, 'bestellung':bestellung}
return render(request, 'shop/kasse.html', ctx)
@csrf_exempt
def artikelBackend(request):
daten = json.loads(request.body)
artikelID = daten['artikelID']
action = daten['action']
kunde = request.user.kunde
artikel = Artikel.objects.get(id=artikelID)
bestellung, created = Bestellung.objects.get_or_create(kunde=kunde, erledigt=False)
bestellteArtikel, created = BestellteArtikel.objects.get_or_create(bestellung=bestellung, artikel=artikel)
if action == 'bestellen':
bestellteArtikel.menge = (bestellteArtikel.menge +1)
messages.success(request, 'Artikel wurde zum Warenkorb hinzugefügt.')
elif action == 'entfernen':
bestellteArtikel.menge = (bestellteArtikel.menge -1)
messages.warning(request, 'Artikel wurde aus dem Warenkorb entfernt.')
bestellteArtikel.save()
if bestellteArtikel.menge <=0:
bestellteArtikel.delete()
return JsonResponse("Artikel hinzugefügt", safe=False)
def loginSeite(request): # der request enthält die Daten die also benutzername und pw die im HTML template dann eingegeben werden
seite = 'login'
if request.method == 'POST':
benutzername = request.POST['benutzername']
passwort = request.POST['passwort']
# jetzt muss geguckt werden ob die Daten auch wirklich valide sind
benutzer = authenticate(request, username=benutzername, password=passwort) # username und password sind die Daten, die in einem user objekt gepeichert sind
if benutzer is not None: # Wenn in der Variable benutzer daten vorhanden sind
login(request, benutzer)
return redirect('shop') # mit redirect kann man automatische Seitenweiterleitungen einrichten
else:
messages.error(request, 'Benutzername oder Passwort nicht korrekt.')
return render(request, 'shop/login.html', {'seite':seite})
def logoutBenutzer(request):
logout(request)
return redirect('shop')
def regBenutzer(request):
seite = 'req'
form = EigeneUserCreationForm
if request.method == 'POST':
form = EigeneUserCreationForm(request.POST) #request.poser enthält die übermittelten Daten also Benutzername und Passwort
if form.is_valid():
benutzer = form.save(commit=False)
benutzer.save()
kunde = Kunde(name=request.POST['username'], benutzer=benutzer)
kunde.save()
bestellung = Bestellung(kunde=kunde)
bestellung.save()
login(request, benutzer)
return redirect('shop')
else:
messages.error(request, 'Fehlerhafte Eingabe')
ctx = {'form':form, 'seite':seite}
return render(request, 'shop/login.html', ctx)
def bestellen(request):
auftrags_id = uuid.uuid4()
daten = json.loads(request.body)
if request.user.is_authenticated:
kunde = request.user.kunde
bestellung, created = Bestellung.objects.get_or_create(kunde=kunde, erledigt=False)
gesamtpreis = float(daten['benutzerDaten']['gesamtpreis'])
bestellung.auftrags_id = auftrags_id
bestellung.erledigt = True
bestellung.save()
Adresse.objects.create(
kunde=kunde,
bestellung=bestellung,
adresse=daten['lieferadresse']['adresse'],
plz=daten['lieferadresse']['plz'],
stadt=daten['lieferadresse']['stadt'],
land=daten['lieferadresse']['land'],
)
else:
print("nicht eingeloggt")
messages.success(request, 'Vielen Dank für ihre Bestellung!')
return JsonResponse('Bestellung erfolgreich', safe=False)
Javascript Datei:
Code: Alles auswählen
// hiermit haben wir unser Queryset
let bestellenButtons = document.getElementsByClassName('warenkorb-bestellen')
for (let i = 0; i < bestellenButtons.length; i++){
bestellenButtons[i].addEventListener('click', function(){
let artikelID = this.dataset.artikel;
let action = this.dataset.action;
updateKundenBestellung(artikelID, action)
})
}
function updateKundenBestellung(artikelID, action){
// mit dem Klick auf dem Button rufen wir in der fetch api die url "/artikel_backend/"; auf und schicken mit post die artikelid und die action an die artikelBackend view
let url = "/artikel_backend/";
fetch(url, {
method: 'post',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken,
},
body: JSON.stringify({'benutzerDaten': benutzerDaten, 'lieferadresse': lieferadresse})
})
.then(()=>location.reload())
}
//Kasse
let formular = document.getElementById('formular')
let gesamtpreis = document.getElementById('gesamtpreis').value
formular.addEventListener('submit', function(e){
e.preventDefault()
document.getElementById('formular-button').classList.add('d-none');
document.getElementById('bezahlen-info').classList.remove('d-none');
})
document.getElementById('bezahlen-button').addEventListener('click', function(e){
submitFormular()
})
function submitFormular(){
let benutzerDaten = {
'name': formular.inputName.value,
'email': formular.inputEmail.value,
'gesamtpreis': gesamtpreis
}
let lieferadresse = {
'adresse': formular.inputAdresse.value,
'plz': formular.inputPlz.value,
'stadt': formular.inputStadt.value,
'land': formular.inputLand.value,
}
console.log(benutzerDaten, lieferadresse)
// Jetzt werden die Daten an das Backende gesendet
let url = "/bestellen/";
fetch(url, {
method: 'post',
headers:{
'Content-Type':'application/json',
'X-CSRFToken':csrftoken,
},
body:JSON.stringify({'benutzerDaten':benutzerDaten, 'lieferadresse':lieferadresse})
})
.then(()=>window.location.href="/")
}
Code: Alles auswählen
{% extends 'shop/index.html' %}
{% block content %}
<div class="row mt-4">
<div class="col-4">
<div class="shadow p-4">
<h3>Bestellübersicht</h3>
<hr>
{% for artikel in artikels %}
<div class="d-flex">
<p class="p-2">{{artikel.menge}}</p>
<p class="me-auto p-2">{{artikel.artikel.name}}</p>
<p class="p-2">{{artikel.get_summe|floatformat:2}} €</p>
</div>
{% endfor %}
<hr>
<div class="d-flex">
<p class="me-auto fw-bold p-2">Menge: {{bestellung.get_gesamtmenge}}</p>
<p class="fw-bold p-2">Gesamtpreis: {{bestellung.get_gesamtpreis|floatformat:2}} €</p>
<input type="number" class="d-none" id="gesamtpreis" value={{bestellung.get_gesamtpreis|floatformat:2}}> <!--jetzt können wir mithilfe id=gesamtpreis auch in der warenkorb.js drauf zuzugreifen-->
</div>
</div>
</div>
<div class="col-8">
<div class="shadow p-4">
<form id="formular" class="row g-3"><!--mit id='formular' können wir das formular eindeutig ansprechen in js greifen wir dann auf diese id zu-->
<div class="col-md-6">
<label for="inputName" class="form-label">Name</label>
<input type="text" class="form-control" id="inputName" value={{request.user|title}}> <!--mit value kann man ein Eingabefeld mit einem Inhalt vorbelegen-->
</div>
<div class="col-md-6">
<label for="inputEmail" class="form-label">Email</label>
<input type="email" class="form-control" id="inputEmail" value="{{request.user.email}}" required>
</div>
<div class="col-12">
<label for="inputAddress" class="form-label">Addresse</label>
<input type="text" class="form-control" id="inputAdresse" required>
</div>
<div class="col-md-2">
<label for="inputPlz" class="form-label">PLZ</label>
<input type="text" class="form-control" id="inputPlz" required>
</div>
<div class="col-md-5">
<label for="inputStadt" class="form-label">Stadt</label>
<input type="text" class="form-control" id="inputStadt" required>
</div>
<div class="col-md-5">
<label for="inputLand" class="form-label">Land</label>
<input type="text" class="form-control" id="inputLand" required>
</div>
<div class="col-12 d-flex justify-content-end">
<button type="submit" id="formular-button" class="btn btn-secondary" >weiter</button>
</div>
</form>
<div class="d-flex d-none" id="bezahlen-info">
<p class="me-auto fw-bold">Zahlung: PayPal</p>
<button class="btn btn-danger" id="bezahlen-button">bezahlen</button>
</div>
</div>
</div>
</div>
{% endblock content %}