Django Python 表单 - 提交具有多个表单和表单集的复杂视图
Django Python Forms - submitting complex view with multiple forms and formsets
想象一下这个概念,
我有一辆出租车,可以由团体订购一整天多次访问,我应该为每次预订指定一名领队。
现在我有一个预订 (PNR) 包含 Clients 旅行路线,以及一个组长 (Operator ) 分配给该预订。
我的观点是:
- 用于选择 运算符的表单
- 表单集添加 客户端
在此视图中,我试图通过 ajax
分别保存每个表单或通过视图底部的按钮保存表单的所有数据来让用户更轻松。
我已经搜索了几天,我在这两个链接上找到了最近的方法 1 & 2 但仍然无法使我的代码 运行 正确并做它应该做的事情. :( 将不胜感激任何支持!
我的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
我的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)
我的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)
我的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'),
最后是我的 template.html:(对于 new 和 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>
pnr
没有添加到 request
对象,所以 request.pnr
没有意义。您需要通过 URL 传递 PNR
的 id
,这样就可以在视图中访问它:
- 在 urls.py 中,确保
edit_pnr
视图的 url 获得 pnr_id
:类似于 path('pnr/<int:pnr_id>/edit/', ..., name="existing_pnr")
.
- 在您的模板中,构建用于编辑 pnr 的 url,如下所示:
{% url 'existing_pnr' pnr_id=pnr %}
- 在您看来,收到
pnr_id
:def edit_pnr(request, pnr_id): ...
现在您可以像这样获取正在编辑的 PNR
:pnr = get_object_or_404(PNR, pk=pnr_id)
如果有人试图访问不存在的 [=14],它将正确 return 404 Not Found =].
想象一下这个概念, 我有一辆出租车,可以由团体订购一整天多次访问,我应该为每次预订指定一名领队。 现在我有一个预订 (PNR) 包含 Clients 旅行路线,以及一个组长 (Operator ) 分配给该预订。
我的观点是:
- 用于选择 运算符的表单
- 表单集添加 客户端
在此视图中,我试图通过 ajax
分别保存每个表单或通过视图底部的按钮保存表单的所有数据来让用户更轻松。
我已经搜索了几天,我在这两个链接上找到了最近的方法 1 & 2 但仍然无法使我的代码 运行 正确并做它应该做的事情. :( 将不胜感激任何支持!
我的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
我的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)
我的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)
我的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'),
最后是我的 template.html:(对于 new 和 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>
pnr
没有添加到 request
对象,所以 request.pnr
没有意义。您需要通过 URL 传递 PNR
的 id
,这样就可以在视图中访问它:
- 在 urls.py 中,确保
edit_pnr
视图的 url 获得pnr_id
:类似于path('pnr/<int:pnr_id>/edit/', ..., name="existing_pnr")
. - 在您的模板中,构建用于编辑 pnr 的 url,如下所示:
{% url 'existing_pnr' pnr_id=pnr %}
- 在您看来,收到
pnr_id
:def edit_pnr(request, pnr_id): ...
现在您可以像这样获取正在编辑的 PNR
:pnr = get_object_or_404(PNR, pk=pnr_id)
如果有人试图访问不存在的 [=14],它将正确 return 404 Not Found =].