Reputation:
I have an issue with my Django forms and combining it with data from my database.
Do you guys have any tips or input how I can make my code more "safe"? Currently, I am skipping all the provided security Django provides with cleaned_data and is_valid(). The reason why is that I don't know how to do it.
views.py
from django.shortcuts import render
from .models import Ticket
from tickets.models import Order, Entry
# Create your views here.
def choose_ticket_and_quantity(request):
tickets = Ticket.objects.all()
if request.POST:
o = Order.objects.create()
request.session['order_id'] = o.order_id
ticket_id = request.POST.getlist('ticket_id')
ticket_quantity = request.POST.getlist('ticket_quantity')
for x in range(len(ticket_id)):
if int(ticket_quantity[x]) > 0:
e = Entry(
order=Order.objects.get(order_id = o.order_id),
ticket=Ticket.objects.get(id = ticket_id[x]),
quantity=ticket_quantity[x]
).save()
return render(request, "tickets/choose_ticket_and_quantity.html", {"tickets": tickets})
models.py
class Ticket(models.Model):
description = models.TextField()
name = models.CharField(max_length=120)
price_gross = models.DecimalField(max_digits=19, decimal_places=2)
quantity = models.IntegerField()
choose_ticket_and_quantity.html
<form action="" method="post">
{% csrf_token %}
{% for ticket in tickets %}
<input type="hidden" name="ticket_id" value="{{ ticket.id }}">
{{ ticket.name }}
<select name="ticket_quantity" >
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
{% endfor %}
<p><input type="submit" value="Checkout"></p>
</form>
Here what I currently tried/started within forms.py But I don't know how to render the *.html while getting the ticket data from its model.
from django import forms
#Currently not used
INT_CHOICES = [tuple([x,x]) for x in range(0,11)]
class TicketForm(forms.Form):
ticket_quantity = forms.IntegerField(widget=forms.Select(choices=INT_CHOICES))
Upvotes: 1
Views: 478
Reputation: 1605
You can create a EntryModelForm
for your Entry
model and then create a FormSet of EntryModelForm
.
Here is sample view function:
from django.forms import formset_factory
def choose_ticket_and_quantity(request):
tickets = []
for ticket in Ticket.objects.all():
tickets.append({'ticket': ticket})
EntryFormSet = formset_factory(EntryModelForm, extra=0)
formset = EntryFormSet(initial=tickets)
if request.POST:
o = Order.objects.create()
formset = EntryFormSet(request.POST, initial=tickets)
for form in formset:
if form.is_valid():
entry = form.save(commit=False)
entry.order = o
entry.save()
return render(request, "tickets/choose_ticket_and_quantity.html",
{'formset': formset})
I guess your entry model class might be something like the following:
class Entry(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
quantity = models.IntegerField(choices=INT_CHOICES)
Here is the form class:
class EntryModelForm(forms.ModelForm):
class Meta:
model=Entry
exclude = ('order',)
Here is the HTML template:
<form action="" method="post">
{% csrf_token %}
{{ formset }}
<p><input type="submit" value="Checkout"></p>
</form>
Upvotes: 1