Публикация данных имеет форму ввода, но модель Django не сохраняет ее - PullRequest
1 голос
/ 25 октября 2019

Я просмотрел кучу других постов, но не могу найти ничего подходящего моему сценарию. У меня есть немного данных, которые встречаются в POST, но потом, когда я сохраняю форму - данные не появляются в базе данных.

Я немного озадачен, почему это так иЯ пробовал разные вещи, но ни одна из них, похоже, не относится к моей ситуации. Большинство из них связано с тем, что данные не публикуются, мои данные публикуются, они просто не сохраняются.

У меня есть следующая модель:

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)

Вот мой PaymentForm:

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") 

Этот оператор print после действительной формы печатает так:

<QueryDict: {'csrfmiddlewaretoken': ['3blahblahblah'], 'amount': ['9.10'], 'method': ['Check'], 'check_number': ['123455'], 'stripe_id': ['']}>

У меня проблема в следующем: когда пользователь выбирает Check в качестве платежа и сохраняет платеж (с номером чека), номер чека не сохраняется в базе данных.

Как мы можемвидите, данные request.POST показывают все данные там (включая номер чека) - но в базе данных check_number не сохраняется, когда работает .save().

Что может сделать это, икак мне это исправить?

1 Ответ

2 голосов
/ 25 октября 2019

Вы должны печатать form.cleaned_data, а не form.data, после is_valid. Если бы вы это сделали, вы бы увидели, что check_number пуст. Причина этого заключается в том, что вы ничего не возвращаете из вашего clean_check_number метода. Вам всегда нужно возвращать очищенное значение из этих методов.

...