在保存到数据库之前访问 Django 中提交的表单数据以供使用的最佳实践
Best practice for accessing submitted form data in django for use before saving to database
我正在 Django 中开发一个应用程序,我想在其中将用户发票详细信息保存到数据库中。来自用户的输入之一是支付类型的选择。在我保存到发票之前,我应该选择这个选择值并从数据库中检索金额。这是我到目前为止所做的。它运行良好,但我真的怀疑这是否是正确的方法。
Models.py
class Invoice(models.Model):
invoice_status_choices = [
('1', 'Pending'),
('2', 'Paid'),
('3', 'Cancelled')
]
invoice_number = models.CharField(max_length = 500, default = increment_invoice_number, null = True, blank = True)
description = models.CharField(max_length=100, blank=True)
customer = models.ForeignKey(User, on_delete=models.CASCADE)
payment_date = models.DateTimeField(blank=True, null=True)
paid_amount = models.DecimalField(max_digits=15, decimal_places=2, default=0)
invoice_status = models.IntegerField(choices=invoice_status_choices, default=1)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.invoice_number)
class InvoiceItem(models.Model):
invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE)
listing = models.ForeignKey('listings.Listing', on_delete=models.CASCADE)
payment_type = models.ForeignKey('SubscriptionType', on_delete=models.CASCADE)
amount = models.DecimalField(max_digits=6, decimal_places=2)
quantity = models.IntegerField(default=1)
def __str__(self):
return f'{self.invoice.invoice_number} Items'
class SubscriptionType(models.Model):
subscription_type = models.CharField(max_length=20)
frequency = models.PositiveIntegerField()
period = models.ForeignKey(PeriodNames, on_delete=models.CASCADE)
rate = models.DecimalField(max_digits=6, decimal_places=2, default=0)
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.subscription_type
这是我需要帮助的视图。关注点是第一个函数:get_invoice_item_amount
。完整的视图函数有:
view.py
def get_invoice_item_amount(payment_type):
subscription_type = SubscriptionType.objects.get(id=payment_type)
amount = subscription_type.rate
return amount
@login_required
def create_invoice(request):
"""
Allows a user to select list items.
"""
user = request.user
invoice_form = InvoiceForm()
InvoiceItemFormset = inlineformset_factory(Invoice, InvoiceItem, form=InvoiceItemForm, extra=1)
if request.method == 'POST':
invoice_form = InvoiceForm(request.POST)
formset = InvoiceItemFormset(request.POST, request.FILES)
if invoice_form and formset.is_valid():
# try:
# with transaction.atomic():
#
# except IntegrityError: #If the transaction failed
# messages.error(request, 'There was an error creating an invoice.')
# return redirect(reverse('profile-settings'))
# return redirect("my_property_detail", property.id)
invoice = invoice_form.save(commit=False)
invoice.customer = request.user
invoice_data = invoice.save()
for f in formset:
# amount = get_invoice_item_amount(f.cleaned_data['payment_type'].id)
invoice_item = InvoiceItem(
invoice=invoice,
listing=f.cleaned_data['listing'],
quantity=f.cleaned_data['quantity'],
payment_type=f.cleaned_data['payment_type'],
amount = get_invoice_item_amount(f.cleaned_data['payment_type'].id))
invoice_item.save()
print("Data saved successfully!")
else:
print("Failed to validate")
else:
form = InvoiceForm()
formset = InvoiceItemFormset()
for n in formset:
n.fields['listing'].queryset = Listing.objects.filter(status=False, listing_owner=user)
context = {
'form': invoice_form,
'formset': formset
}
return render(request, 'payments/create_invoice.html', context)
我在保存 invoice_item
之前调用表单集中的函数。那是正确的方法吗?或者有推荐的方法。
这是 cleaned_data
的一个完全有效的用例。访问 cleaned_data
完全没有问题。
请注意,如果您以某种方式修改 cleaned_data
中的值,则在保存基于它的实例时可能会导致错误。
但在这种情况下,您只读取一个值,完全没有问题..
我正在 Django 中开发一个应用程序,我想在其中将用户发票详细信息保存到数据库中。来自用户的输入之一是支付类型的选择。在我保存到发票之前,我应该选择这个选择值并从数据库中检索金额。这是我到目前为止所做的。它运行良好,但我真的怀疑这是否是正确的方法。
Models.py
class Invoice(models.Model):
invoice_status_choices = [
('1', 'Pending'),
('2', 'Paid'),
('3', 'Cancelled')
]
invoice_number = models.CharField(max_length = 500, default = increment_invoice_number, null = True, blank = True)
description = models.CharField(max_length=100, blank=True)
customer = models.ForeignKey(User, on_delete=models.CASCADE)
payment_date = models.DateTimeField(blank=True, null=True)
paid_amount = models.DecimalField(max_digits=15, decimal_places=2, default=0)
invoice_status = models.IntegerField(choices=invoice_status_choices, default=1)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.invoice_number)
class InvoiceItem(models.Model):
invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE)
listing = models.ForeignKey('listings.Listing', on_delete=models.CASCADE)
payment_type = models.ForeignKey('SubscriptionType', on_delete=models.CASCADE)
amount = models.DecimalField(max_digits=6, decimal_places=2)
quantity = models.IntegerField(default=1)
def __str__(self):
return f'{self.invoice.invoice_number} Items'
class SubscriptionType(models.Model):
subscription_type = models.CharField(max_length=20)
frequency = models.PositiveIntegerField()
period = models.ForeignKey(PeriodNames, on_delete=models.CASCADE)
rate = models.DecimalField(max_digits=6, decimal_places=2, default=0)
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.subscription_type
这是我需要帮助的视图。关注点是第一个函数:get_invoice_item_amount
。完整的视图函数有:
view.py
def get_invoice_item_amount(payment_type):
subscription_type = SubscriptionType.objects.get(id=payment_type)
amount = subscription_type.rate
return amount
@login_required
def create_invoice(request):
"""
Allows a user to select list items.
"""
user = request.user
invoice_form = InvoiceForm()
InvoiceItemFormset = inlineformset_factory(Invoice, InvoiceItem, form=InvoiceItemForm, extra=1)
if request.method == 'POST':
invoice_form = InvoiceForm(request.POST)
formset = InvoiceItemFormset(request.POST, request.FILES)
if invoice_form and formset.is_valid():
# try:
# with transaction.atomic():
#
# except IntegrityError: #If the transaction failed
# messages.error(request, 'There was an error creating an invoice.')
# return redirect(reverse('profile-settings'))
# return redirect("my_property_detail", property.id)
invoice = invoice_form.save(commit=False)
invoice.customer = request.user
invoice_data = invoice.save()
for f in formset:
# amount = get_invoice_item_amount(f.cleaned_data['payment_type'].id)
invoice_item = InvoiceItem(
invoice=invoice,
listing=f.cleaned_data['listing'],
quantity=f.cleaned_data['quantity'],
payment_type=f.cleaned_data['payment_type'],
amount = get_invoice_item_amount(f.cleaned_data['payment_type'].id))
invoice_item.save()
print("Data saved successfully!")
else:
print("Failed to validate")
else:
form = InvoiceForm()
formset = InvoiceItemFormset()
for n in formset:
n.fields['listing'].queryset = Listing.objects.filter(status=False, listing_owner=user)
context = {
'form': invoice_form,
'formset': formset
}
return render(request, 'payments/create_invoice.html', context)
我在保存 invoice_item
之前调用表单集中的函数。那是正确的方法吗?或者有推荐的方法。
这是 cleaned_data
的一个完全有效的用例。访问 cleaned_data
完全没有问题。
请注意,如果您以某种方式修改 cleaned_data
中的值,则在保存基于它的实例时可能会导致错误。
但在这种情况下,您只读取一个值,完全没有问题..