Django Inlineformsets - 使用 django-extra-views 进行自定义验证
Django Inlineformsets - Custom validation with django-extra-views
所以我有一个关于 django-extra-views 的 form_valid 的问题。我使用 CreateWithInlinesView 方法创建了一个具有多个内联表单集的表单。
称为“订单”的基本表单包含两个不同的表单集,“预订”和“付款”。一个订单必须至少包含一个预订,但在创建订单时不一定需要付款。
尽管如此,仍会生成付款表格。我想在“payment_amount”> 0 上验证付款表单。如果在创建订单时没有付款,则不应保存 PaymentInline。
views.py
class BookingInline(InlineFormSetFactory):
model = Booking
form_class = BookingForm
prefix = 'booking_formset'
factory_kwargs = {
'extra': 0,
'min_num': 1,
'validate_min': True,
'can_delete': True
}
class PaymentInline(InlineFormSetFactory):
model = Payment
form_class = PaymentForm
prefix = 'payment_formset'
factory_kwargs = {
'extra': 1,
'min_num': 0,
'validate_min': False,
'can_delete': True
}
class OrderCreateView(NamedFormsetsMixin, CreateWithInlinesView):
model = Order
inlines = [BookingInline, PaymentInline]
inlines_names = ['booking_formset', 'payment_formset']
form_class = OrderForm
template_name = 'orders/order_form.html'
def get_success_url(self):
return reverse_lazy('order_detail', kwargs={'pk': self.object.pk})
def forms_valid(self, form, inlines):
"""
If the form and formsets are valid, save the associated models.
"""
self.object = form.save(commit=False)
self.object.created_by = self.request.user
form.save(commit=True)
for formset in inlines:
formset.save()
return HttpResponseRedirect(self.get_success_url())
所以逻辑需要像下面这样,虽然我得到一个错误说 'Order' 对象没有属性 'payment',因为它是一个反向关系...
views.py
def forms_valid(self, form, inlines):
"""
If the form and formsets are valid, save the associated models.
"""
self.object = form.save(commit=False)
self.object.created_by = self.request.user
form.save(commit=True)
for booking_formset in inlines:
booking_formset.save()
for payment_formset in inlines:
if self.object.payment.amount > 0:
payment_formset.save()
else:
pass
return HttpResponseRedirect(self.get_success_url())
有谁知道如何处理表单中的不同表单集?
提前致谢!
我不确定您的表单集上有哪些字段可用,但您可以使用 commit=False
保存,然后遍历未提交的付款实例以获得总付款金额。
def forms_valid(self, form, inlines):
booking_formset = inlines[0]
payment_formset = inlines[1]
self.object = form.save(commit=False)
self.object.created_by = self.request.user
form.save(commit=True)
booking_formset.save()
payments = payment_formset.save(commit=False)
total_payment = sum(payment.amount for payment in payments)
if total_payment > 0:
payment_formset.save()
return HttpResponseRedirect(self.get_success_url())
更新:
行booking_formset in inlines:
和payment_formset in inlines:
会导致问题。假设 inlines
是一个列表,您将对该列表进行两次迭代。这相当于做下面的事情:
lst = [1, 2]
for x in lst:
print(x)
for y in lst:
print(y)
>>> 1
>>> 2
>>> 1
>>> 2
所以我有一个关于 django-extra-views 的 form_valid 的问题。我使用 CreateWithInlinesView 方法创建了一个具有多个内联表单集的表单。
称为“订单”的基本表单包含两个不同的表单集,“预订”和“付款”。一个订单必须至少包含一个预订,但在创建订单时不一定需要付款。
尽管如此,仍会生成付款表格。我想在“payment_amount”> 0 上验证付款表单。如果在创建订单时没有付款,则不应保存 PaymentInline。
views.py
class BookingInline(InlineFormSetFactory):
model = Booking
form_class = BookingForm
prefix = 'booking_formset'
factory_kwargs = {
'extra': 0,
'min_num': 1,
'validate_min': True,
'can_delete': True
}
class PaymentInline(InlineFormSetFactory):
model = Payment
form_class = PaymentForm
prefix = 'payment_formset'
factory_kwargs = {
'extra': 1,
'min_num': 0,
'validate_min': False,
'can_delete': True
}
class OrderCreateView(NamedFormsetsMixin, CreateWithInlinesView):
model = Order
inlines = [BookingInline, PaymentInline]
inlines_names = ['booking_formset', 'payment_formset']
form_class = OrderForm
template_name = 'orders/order_form.html'
def get_success_url(self):
return reverse_lazy('order_detail', kwargs={'pk': self.object.pk})
def forms_valid(self, form, inlines):
"""
If the form and formsets are valid, save the associated models.
"""
self.object = form.save(commit=False)
self.object.created_by = self.request.user
form.save(commit=True)
for formset in inlines:
formset.save()
return HttpResponseRedirect(self.get_success_url())
所以逻辑需要像下面这样,虽然我得到一个错误说 'Order' 对象没有属性 'payment',因为它是一个反向关系...
views.py
def forms_valid(self, form, inlines):
"""
If the form and formsets are valid, save the associated models.
"""
self.object = form.save(commit=False)
self.object.created_by = self.request.user
form.save(commit=True)
for booking_formset in inlines:
booking_formset.save()
for payment_formset in inlines:
if self.object.payment.amount > 0:
payment_formset.save()
else:
pass
return HttpResponseRedirect(self.get_success_url())
有谁知道如何处理表单中的不同表单集?
提前致谢!
我不确定您的表单集上有哪些字段可用,但您可以使用 commit=False
保存,然后遍历未提交的付款实例以获得总付款金额。
def forms_valid(self, form, inlines):
booking_formset = inlines[0]
payment_formset = inlines[1]
self.object = form.save(commit=False)
self.object.created_by = self.request.user
form.save(commit=True)
booking_formset.save()
payments = payment_formset.save(commit=False)
total_payment = sum(payment.amount for payment in payments)
if total_payment > 0:
payment_formset.save()
return HttpResponseRedirect(self.get_success_url())
更新:
行booking_formset in inlines:
和payment_formset in inlines:
会导致问题。假设 inlines
是一个列表,您将对该列表进行两次迭代。这相当于做下面的事情:
lst = [1, 2]
for x in lst:
print(x)
for y in lst:
print(y)
>>> 1
>>> 2
>>> 1
>>> 2