Post 数据有表单输入,但 Django modelform 没有保存它
Post data has form input but Django modelform is not saving it
我浏览了很多其他帖子 - 但我找不到任何适合我的情况的帖子。我在 POST 中遇到了一些数据,但是当我保存表单时 - 数据没有出现在数据库中。
我有点困惑为什么会这样,我尝试了各种方法,但 none 似乎确实适用于我的情况。大多数与数据未发布有关,我的数据已发布,只是没有保存。
我有以下型号:
class Payment(models.Model):
METHODS = (
("Cash", "Cash"),
("Check", "Check"),
("Credit Card", "Credit Card")
)
amount = models.DecimalField(decimal_places=2, max_digits=6)
method = models.CharField(
max_length=15,
choices=METHODS,
default="Credit Card"
)
stripe_id = models.CharField(max_length=255, blank=True, null=True)
check_number = models.IntegerField(blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
这是我的付款表格:
class PaymentForm(forms.ModelForm):
method = forms.CharField(
max_length=25,
widget=forms.TextInput(attrs={
"class": "form-control",
"readonly": "True",
})
)
amount = forms.DecimalField(
decimal_places=2,
max_digits=6,
widget=forms.TextInput(attrs={
"class": "form-control",
"readonly": "True",
})
)
stripe_id = forms.CharField(
widget=forms.HiddenInput(),
required=False
)
check_number = forms.IntegerField(
widget=forms.TextInput(attrs={"class": "form-control"}),
required=False
)
class Meta:
model = Payment
fields = (
'amount',
'method',
'stripe_id',
'check_number',
)
def clean_check_number(self):
method = self.cleaned_data["method"]
check_number = self.cleaned_data["check_number"]
if method == "Check" and not check_number:
raise forms.ValidationError("Check number is required.")
这是我的 view.py
函数,它与 POST:
相关
if request.method == "POST":
# Create a copy of the POST data so we can input data for CC payments
post_data = request.POST.copy()
# Set the PaymentForm with the copied data (muteable)
# required for some of the stripe stuff we do
payment_form = PaymentForm(post_data)
if 'stripeToken' in request.POST:
# This is wrapped in extensive try/catch in reality but I left
# it out for brevity
charge = stripe.Charge.create(
amount=stripe_cost,
currency="usd",
description="Payment",
source=request.POST["stripeToken"],
receipt_email=request.POST["stripeEmail"],
)
# add things to the form that aren't there
# from the stripe reply
payment_form.data['method'] = "Credit Card"
payment_form.data['stripe_id'] = charge["id"]
# This part works fine
if payment_form.is_valid():
# either a non-stripe payment
# or the next step after the stripe stuff is don
payment_form.save(commit=False)
print(payment_form.data)
payment = payment_form.save()
# The data saves to the DB, but the check_number is empty!
messages.success(request, "Thank you for your payment!")
return redirect("my_app:index")
表单有效后的打印语句打印出来是这样的:
<QueryDict: {'csrfmiddlewaretoken': ['3blahblahblah'], 'amount': ['9.10'], 'method': ['Check'], 'check_number': ['123455'], 'stripe_id': ['']}>
我遇到的问题是:当用户选择 Check
作为付款并保存付款(带有支票号码)时,支票号码不会保存到数据库中。
正如我们所见,request.POST
数据显示了那里的所有数据(包括支票号码)——但是在数据库中 check_number
没有被存储,而 .save()
是运行.
什么可能导致这种情况发生,我该如何修正?
您应该在 is_valid 之后打印 form.cleaned_data
,而不是 form.data
。如果这样做,您会看到 check_number 是空的。原因是您 return 没有从您的 clean_check_number
方法中得到任何东西。您始终需要 return 从这些方法中清除的值。
我浏览了很多其他帖子 - 但我找不到任何适合我的情况的帖子。我在 POST 中遇到了一些数据,但是当我保存表单时 - 数据没有出现在数据库中。
我有点困惑为什么会这样,我尝试了各种方法,但 none 似乎确实适用于我的情况。大多数与数据未发布有关,我的数据已发布,只是没有保存。
我有以下型号:
class Payment(models.Model):
METHODS = (
("Cash", "Cash"),
("Check", "Check"),
("Credit Card", "Credit Card")
)
amount = models.DecimalField(decimal_places=2, max_digits=6)
method = models.CharField(
max_length=15,
choices=METHODS,
default="Credit Card"
)
stripe_id = models.CharField(max_length=255, blank=True, null=True)
check_number = models.IntegerField(blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
这是我的付款表格:
class PaymentForm(forms.ModelForm):
method = forms.CharField(
max_length=25,
widget=forms.TextInput(attrs={
"class": "form-control",
"readonly": "True",
})
)
amount = forms.DecimalField(
decimal_places=2,
max_digits=6,
widget=forms.TextInput(attrs={
"class": "form-control",
"readonly": "True",
})
)
stripe_id = forms.CharField(
widget=forms.HiddenInput(),
required=False
)
check_number = forms.IntegerField(
widget=forms.TextInput(attrs={"class": "form-control"}),
required=False
)
class Meta:
model = Payment
fields = (
'amount',
'method',
'stripe_id',
'check_number',
)
def clean_check_number(self):
method = self.cleaned_data["method"]
check_number = self.cleaned_data["check_number"]
if method == "Check" and not check_number:
raise forms.ValidationError("Check number is required.")
这是我的 view.py
函数,它与 POST:
if request.method == "POST":
# Create a copy of the POST data so we can input data for CC payments
post_data = request.POST.copy()
# Set the PaymentForm with the copied data (muteable)
# required for some of the stripe stuff we do
payment_form = PaymentForm(post_data)
if 'stripeToken' in request.POST:
# This is wrapped in extensive try/catch in reality but I left
# it out for brevity
charge = stripe.Charge.create(
amount=stripe_cost,
currency="usd",
description="Payment",
source=request.POST["stripeToken"],
receipt_email=request.POST["stripeEmail"],
)
# add things to the form that aren't there
# from the stripe reply
payment_form.data['method'] = "Credit Card"
payment_form.data['stripe_id'] = charge["id"]
# This part works fine
if payment_form.is_valid():
# either a non-stripe payment
# or the next step after the stripe stuff is don
payment_form.save(commit=False)
print(payment_form.data)
payment = payment_form.save()
# The data saves to the DB, but the check_number is empty!
messages.success(request, "Thank you for your payment!")
return redirect("my_app:index")
表单有效后的打印语句打印出来是这样的:
<QueryDict: {'csrfmiddlewaretoken': ['3blahblahblah'], 'amount': ['9.10'], 'method': ['Check'], 'check_number': ['123455'], 'stripe_id': ['']}>
我遇到的问题是:当用户选择 Check
作为付款并保存付款(带有支票号码)时,支票号码不会保存到数据库中。
正如我们所见,request.POST
数据显示了那里的所有数据(包括支票号码)——但是在数据库中 check_number
没有被存储,而 .save()
是运行.
什么可能导致这种情况发生,我该如何修正?
您应该在 is_valid 之后打印 form.cleaned_data
,而不是 form.data
。如果这样做,您会看到 check_number 是空的。原因是您 return 没有从您的 clean_check_number
方法中得到任何东西。您始终需要 return 从这些方法中清除的值。