django - 在一个 post 请求中提交多个表单(与单击不同,因为我需要一起处理这两个表单的数据!)
django - submit multiple forms in one post request (different from one click cause I need to process the data of those two forms together!)
我有三个模型 jobposition
、wage
、kitfee
,它们之间存在一对多关系。
class JobPosition(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.ForeignKey(Title, on_delete=models.CASCADE)
...
class Wage(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
amount = models.FloatField(blank=True,null=True)
type = models.CharField(choices=WAGETYPE, max_length=30)
position = models.ForeignKey(JobPosition, related_name='wages', on_delete=models.CASCADE, blank=True, null=True)
class KitFee(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
kit_name = models.CharField(max_length=20, blank=True, null=True)
amount = models.FloatField(blank=True, null=True)
type = models.CharField(choices=WAGETYPE, max_length=30)
position = models.ForeignKey(JobPosition, related_name='kit_fees', on_delete=models.CASCADE, blank=True, null=True)
我正在构建一个用户界面,用户可以在其中创建具有相关工资和 kit_fee 的职位(假设现在只有一份工资和一份工具包费用)。
我面临的问题是我不确定如何以正确的方式发出 post 请求。
我创建了这两个表单并使用模板视图将它们提供给 django 模板。
class JobPositionForm(forms.ModelForm):
class Meta:
model = JobPosition
fields = ['title','city','dept_head','files','department_budget']
...
class WageForm(forms.ModelForm):
class Meta:
model = Wage
exclude = ['id']
我的看法
class NewPosition(MyLoginRequiredMixin,TemplateView):
template_name = 'action/crew/position.html'
def get_context_data(self, **kwargs):
self.project = get_object_or_404(JobProject, id=kwargs['project_id'])
context = super().get_context_data(**kwargs)
context['position_form'] = JobPositionForm(project=self.project, user=self.request.user)
context['wage_form'] = WageForm()
context['kit_fee_form'] = KitFeeForm()
return context
def post(self,request, **kwargs):
print(request.POST)
self.project = get_object_or_404(JobProject, id=kwargs['project_id'])
position_form = JobPositionForm(request.POST, project=self.project, user=self.request.user)
wage_form = WageForm(request.POST)
kit_fee_form = KitFeeForm(request.POST)
print(kit_fee_form.data['amount'])
print(wage_form.data['amount'])
页面呈现流畅,但我现在意识到我不知道如何在单个 post 请求中同时提交这两个表单,也不知道如何在处理时在视图中初始化表单post 请求。
我考虑过使用 formset,但我不知道如何将它用于不同的表单。
我想我总是可以手动使用Javascript解析每个值并将其放入相同的POST...但我是希望可以使用一些不错的 django 功能解决它。特别是因为手动方法不能很好地扩展。
<form id="position_form">
<div id="title_div" style="margin-top: 20px;">
<label for="id_title" style="margin-bottom: 5px;" class="lead">Title</label><br/>
{{position_form.title}}
<div id="city_div" style="margin-top: 20px;" onfocus="$('#title_creation_div').hide();">
<label for="id_city" style="margin-bottom: 5px;" class="lead">City</label><br/>
{{position_form.city}}
</div>
<br>
<div class="inner" style="display: inline-block;margin-right: 5px;margin-left: 5px; text-align: center">
<label for="OtherComp">Department Budget</label><br/>
{{position_form.department_budget}}
</div>
<div class="inner" style="display: inline-block;margin-right: 5px;margin-left: 5px; text-align: center">
<label for="TeamInfo">Department Head</label><br/>
{{ position_form.dept_head }}
</div>
</form>
<form id="wage_form">
<div id="outer" style="width:100%; margin-top: 20px ">
<div class="inner" style="display: inline-block;margin-right: 5px;margin-left: 5px">
<label for="{{ wage_form.amount.id_for_label }}">Rate</label><br/>
{{wage_form.amount}}
</div>
<div class="inner" style="display: inline-block;margin-right: 5px;margin-left: 5px; text-align: center">
<label for="{{ wage_form.type.id_for_label }}">Rate Type</label><br/>
{{wage_form.type}}
</div>
</div>
</form>
有什么想法吗?
编辑
我正在使用此 javascript 将所有表单发送到同一个 post 请求中,它似乎工作正常。但是,我注意到许多字段具有相同的 ID,因此我无法正确启动表单。此外,如果我开始向屏幕添加额外的 wages/kitfee,该过程似乎无法扩展。
$("form").submit(function (e) {
e.preventDefault();
let data_array = $("form").map(function(){
return $(this).serializeArray();
});
data_array.push({csrfmiddlewaretoken: "{{ csrf_token }}"})
console.log(data_array)
$.ajax({
type: "POST",
url: "{% if source == 'edit' %}{% url 'action:edit_position' project.id position.id %}{% else %}{% url 'action:new_position' project.id %}{% endif %}",
data:data_array,
success:function(html){
}
});
});
由于您使用的是模型表单,您可以直接将请求传递到表单实例中以同时处理两个表单...请参阅下面的简单注册场景,其中两个模型表单(User_form 和User_profile_Form) 正在处理中,
Views.py
def signup(request):
registered = False
if request.method == "POST":
user_form = User_form(data=request.POST)
user_profileform = user_profile_form(data=request.POST)
if(user_form.is_valid() and user_profileform.is_valid()):
user = user_form.save()
user.set_password(user.password)
user.save()
profile = user_profileform.save(commit=False)
profile.user = user
if 'profile_picture' in request.FILES:
profile.profile_picture = request.FILES['profile_picture']
profile.save()
registered = True
else:
print(user_form.errors, user_profileform.errors)
更新 1 添加模板部分
<!DOCTYPE html>
{% extends "base.html" %}
{% load static %}
{% load bootstrap_tags %}
{% block title %}
Signup
{% endblock %}
{% block body %}
<div class="container">
{% if registered %}
<h1>Thankyou for REGISTERING with us</h1>
<br>
<a href="{% url 'homepage:home' %}"> click here to continue </a>
{% else %}
<a href="{% url 'registration:signin' %}"> <h4 style="text-align: center;" > Already have an account ? </h4></a>
<h3>PLEASE fill the registration form below</h3>
<form enctype="multipart/form-data" method="POST">
<div class="container sign-form">
{% csrf_token %}
<h4>
<u>Account Information : </u>
{{ user_form |as_bootstrap }}
<br>
<hr>
<br>
<u><h4>Personal Information :</h4></u>
{{ user_profileform |as_bootstrap }}
</h4>
<input type="submit" class = "btn btn-primary" name="submit" value="Sign Up" style="margin: 0% 15%; width: 70%">
</div>
</form>
{% endif %}
{% endblock %}
我有三个模型 jobposition
、wage
、kitfee
,它们之间存在一对多关系。
class JobPosition(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.ForeignKey(Title, on_delete=models.CASCADE)
...
class Wage(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
amount = models.FloatField(blank=True,null=True)
type = models.CharField(choices=WAGETYPE, max_length=30)
position = models.ForeignKey(JobPosition, related_name='wages', on_delete=models.CASCADE, blank=True, null=True)
class KitFee(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
kit_name = models.CharField(max_length=20, blank=True, null=True)
amount = models.FloatField(blank=True, null=True)
type = models.CharField(choices=WAGETYPE, max_length=30)
position = models.ForeignKey(JobPosition, related_name='kit_fees', on_delete=models.CASCADE, blank=True, null=True)
我正在构建一个用户界面,用户可以在其中创建具有相关工资和 kit_fee 的职位(假设现在只有一份工资和一份工具包费用)。
我面临的问题是我不确定如何以正确的方式发出 post 请求。
我创建了这两个表单并使用模板视图将它们提供给 django 模板。
class JobPositionForm(forms.ModelForm):
class Meta:
model = JobPosition
fields = ['title','city','dept_head','files','department_budget']
...
class WageForm(forms.ModelForm):
class Meta:
model = Wage
exclude = ['id']
我的看法
class NewPosition(MyLoginRequiredMixin,TemplateView):
template_name = 'action/crew/position.html'
def get_context_data(self, **kwargs):
self.project = get_object_or_404(JobProject, id=kwargs['project_id'])
context = super().get_context_data(**kwargs)
context['position_form'] = JobPositionForm(project=self.project, user=self.request.user)
context['wage_form'] = WageForm()
context['kit_fee_form'] = KitFeeForm()
return context
def post(self,request, **kwargs):
print(request.POST)
self.project = get_object_or_404(JobProject, id=kwargs['project_id'])
position_form = JobPositionForm(request.POST, project=self.project, user=self.request.user)
wage_form = WageForm(request.POST)
kit_fee_form = KitFeeForm(request.POST)
print(kit_fee_form.data['amount'])
print(wage_form.data['amount'])
页面呈现流畅,但我现在意识到我不知道如何在单个 post 请求中同时提交这两个表单,也不知道如何在处理时在视图中初始化表单post 请求。
我考虑过使用 formset,但我不知道如何将它用于不同的表单。
我想我总是可以手动使用Javascript解析每个值并将其放入相同的POST...但我是希望可以使用一些不错的 django 功能解决它。特别是因为手动方法不能很好地扩展。
<form id="position_form">
<div id="title_div" style="margin-top: 20px;">
<label for="id_title" style="margin-bottom: 5px;" class="lead">Title</label><br/>
{{position_form.title}}
<div id="city_div" style="margin-top: 20px;" onfocus="$('#title_creation_div').hide();">
<label for="id_city" style="margin-bottom: 5px;" class="lead">City</label><br/>
{{position_form.city}}
</div>
<br>
<div class="inner" style="display: inline-block;margin-right: 5px;margin-left: 5px; text-align: center">
<label for="OtherComp">Department Budget</label><br/>
{{position_form.department_budget}}
</div>
<div class="inner" style="display: inline-block;margin-right: 5px;margin-left: 5px; text-align: center">
<label for="TeamInfo">Department Head</label><br/>
{{ position_form.dept_head }}
</div>
</form>
<form id="wage_form">
<div id="outer" style="width:100%; margin-top: 20px ">
<div class="inner" style="display: inline-block;margin-right: 5px;margin-left: 5px">
<label for="{{ wage_form.amount.id_for_label }}">Rate</label><br/>
{{wage_form.amount}}
</div>
<div class="inner" style="display: inline-block;margin-right: 5px;margin-left: 5px; text-align: center">
<label for="{{ wage_form.type.id_for_label }}">Rate Type</label><br/>
{{wage_form.type}}
</div>
</div>
</form>
有什么想法吗?
编辑 我正在使用此 javascript 将所有表单发送到同一个 post 请求中,它似乎工作正常。但是,我注意到许多字段具有相同的 ID,因此我无法正确启动表单。此外,如果我开始向屏幕添加额外的 wages/kitfee,该过程似乎无法扩展。
$("form").submit(function (e) {
e.preventDefault();
let data_array = $("form").map(function(){
return $(this).serializeArray();
});
data_array.push({csrfmiddlewaretoken: "{{ csrf_token }}"})
console.log(data_array)
$.ajax({
type: "POST",
url: "{% if source == 'edit' %}{% url 'action:edit_position' project.id position.id %}{% else %}{% url 'action:new_position' project.id %}{% endif %}",
data:data_array,
success:function(html){
}
});
});
由于您使用的是模型表单,您可以直接将请求传递到表单实例中以同时处理两个表单...请参阅下面的简单注册场景,其中两个模型表单(User_form 和User_profile_Form) 正在处理中,
Views.py
def signup(request):
registered = False
if request.method == "POST":
user_form = User_form(data=request.POST)
user_profileform = user_profile_form(data=request.POST)
if(user_form.is_valid() and user_profileform.is_valid()):
user = user_form.save()
user.set_password(user.password)
user.save()
profile = user_profileform.save(commit=False)
profile.user = user
if 'profile_picture' in request.FILES:
profile.profile_picture = request.FILES['profile_picture']
profile.save()
registered = True
else:
print(user_form.errors, user_profileform.errors)
更新 1 添加模板部分
<!DOCTYPE html>
{% extends "base.html" %}
{% load static %}
{% load bootstrap_tags %}
{% block title %}
Signup
{% endblock %}
{% block body %}
<div class="container">
{% if registered %}
<h1>Thankyou for REGISTERING with us</h1>
<br>
<a href="{% url 'homepage:home' %}"> click here to continue </a>
{% else %}
<a href="{% url 'registration:signin' %}"> <h4 style="text-align: center;" > Already have an account ? </h4></a>
<h3>PLEASE fill the registration form below</h3>
<form enctype="multipart/form-data" method="POST">
<div class="container sign-form">
{% csrf_token %}
<h4>
<u>Account Information : </u>
{{ user_form |as_bootstrap }}
<br>
<hr>
<br>
<u><h4>Personal Information :</h4></u>
{{ user_profileform |as_bootstrap }}
</h4>
<input type="submit" class = "btn btn-primary" name="submit" value="Sign Up" style="margin: 0% 15%; width: 70%">
</div>
</form>
{% endif %}
{% endblock %}