Imagine this concept, I have a Taxi that can be ordered by a group for a full day multiple visits, and I should assign a group leader for each booking. now I have a Booking (PNR) that holds Clients traveling Routes, and a Group Leader (Operator) assigned for that booking.
my view holds these:
in this view I'm trying to make it easier for the user by giving the ability to save each form separately by ajax
or save all data of forms by a button at the bottom of the view.
I've been searching for a few days and I got the nearest approach on these two linkes 1 & 2 but still can't make my code run correctly and do what it's supposed to do. :( ANY SUPPORT WILL BE HIGHLY APPRECIATED!
My models.py:
class Operator (models.Model):
name = models.CharField(max_length=50)
# Other Fields
def __str__(self):
return self.code
class PNR (models.Model):
date_created = models.DateTimeField(auto_now_add=True)
# Other Fields
def __str__(self):
return self.pk
class Client (models.Model):
related_pnr = models.ForeignKey(PNR, on_delete=models.CASCADE)
name = models.CharField(max_length=200)
# Other Fields
def __str__(self):
return self.related_pnr+" "+self.name
My forms.py:
class ChooseOperatorCode(forms.Form):
operator = forms.ModelChoiceField(queryset=Operator.objects.all())
def clean(self, *args, **kwargs):
operator = self.cleaned_data.get('operator')
return super(ChooseOperatorCode, self).clean(*args, **kwargs)
class NewClientForm(forms.Form):
name = forms.CharField(widget=forms.TextInput(attrs={}), label=False, max_length=200)
# Other Fields
def clean(self, *args, **kwargs):
name = self.cleaned_data.get('name')
# Other Fields
return super(NewClientForm, self).clean(*args, **kwargs)
My views.py:
@login_required
def create_pnr(request):
pnr = PNR.objects.create(created_by_user=request.user)
choose_operator_form = ChooseOperatorCode(request.POST or None)
if choose_operator_form.is_valid():
pnr.created_by_operator = choose_operator_form.cleaned_data.get('operator')
pnr.save()
choose_operator_form.save()
clients_form = NewClientForm(request.POST or None)
if clients_form.is_valid():
client = Client()
client.related_pnr = pnr.pk
client.name = clients_form.cleaned_data.get('name')
client.save()
clients_form.save()
context = {
'pnr': pnr.pk,
'choose_operator_form': choose_operator_form,
'clients_form': clients_form,
}
return render(request, 'reservation_new.html', context)
@login_required
def edit_pnr(request, pnr_id):
pnr = PNR.objects.get(id=pnr_id)
choose_operator_form = ChooseOperatorCode(request.POST or None)
if choose_operator_form.is_valid():
pnr.created_by_operator = choose_operator_form.cleaned_data.get('operator')
pnr.save()
clients_form = NewClientForm(request.POST or None)
if clients_form.is_valid():
client = Client()
client.related_pnr = pnr.pk
client.name = clients_form.cleaned_data.get('name')
client.save()
clients_form.save()
context = {
'pnr': pnr.pk,
'choose_operator_form': choose_operator_form,
'clients_form': clients_form,
}
return render(request, 'reservation_edit.html', context)
My url.py:
path('operation/reservation/new/', views.create_pnr, name='new_pnr'),
path('operation/reservation/existing/<int:pnr_id>/', views.edit_pnr,
name='existing_pnr'),
And Finally my template.html: (for both new and edit)
<form method="POST" action="{% url 'existing_pnr' pnr_id=pnr %}" id="choose_operator_form">
{% csrf_token %}
{{choose_operator_form}}
</form>
<form method="POST" action="{% url 'existing_pnr' pnr_id=pnr %}" id="clients_form">
{% csrf_token %}
{{clients_form}}
</form>
<script type="javascript">
$(document).('submit', '#choose_operator_form', function(e){
e.preventDefault();
$.ajax({
type:'POST',
url:"{% url 'existing_pnr' %}",
data: $('#choose_operator_form').serialize(),
success: function (result) {
// show success msg
},
error: function (data) {
// show error msg
}
});
});
//same code for clients form
</script>
The pnr
doesn't get added to the request
object, so request.pnr
makes no sense. You need to pass the id
of the PNR
through the URL, that way it can be accessed in the view:
edit_pnr
view gets the pnr_id
: something like path('pnr/<int:pnr_id>/edit/', ..., name="existing_pnr")
.{% url 'existing_pnr' pnr_id=pnr %}
pnr_id
: def edit_pnr(request, pnr_id): ...
Now you can fetch the PNR
that's being edit like this: pnr = get_object_or_404(PNR, pk=pnr_id)
which will correctly return a 404 Not Found if someone tries to access a non-existing PNR
.