Django 表单初始值在渲染时不起作用

问题描述 投票:0回答:1

我有一个模型“Transaction”和 ModelForm 来创建一个:

class Transaction(models.Model):
    """ Invoice model.
     Represents a basic income/outcome transaction. """
    
    title = models.CharField(max_length=32, verbose_name="Title")
    category = models.ForeignKey(Category, related_name="transactions", on_delete=models.CASCADE, null=True, blank=True)
    operation = models.CharField(max_length=8, choices=OPERATION_TYPE, verbose_name="operation")
    value = models.DecimalField(max_digits=14, decimal_places=2, verbose_name="value")
    currency = models.CharField(max_length=3, choices=CURRENCY_CHOICE, verbose_name="currency")
    comment = models.CharField(max_length=255, null=True, blank=True)
    date_created = models.DateField(auto_now_add=True, blank=True, null=True)

    class Meta:
        verbose_name_plural = "Transactions"
        ordering = ["-date_created"]

class NewInvoiceForm(forms.ModelForm):
    category = TreeNodeChoiceField(queryset=Category.objects.all())

    class Meta:
        model = Transaction
        fields = ("title", "category", "operation", "value", "currency")
        help_texts = {
            "operation": _("Money spent/received. For expenses use a negative value.")
        }

我有一个与每个用户链接的偏好模型来存储设置:

class Config(models.Model):
    """ Represents user's preferences. """
    
    user = models.OneToOneField(CustomUser, related_name="config", on_delete=models.CASCADE)
    currency = models.CharField(max_length=3, choices=CURRENCY_CHOICE, default=DEFAULT_SETTINGS["currency"])
    language = models.CharField(max_length=56, choices=LANGUAGE_CHOICE, default=DEFAULT_SETTINGS["language"])

    class Meta:
        verbose_name = "config"
        verbose_name_plural = "configs"

我正在尝试从

Config
模型获取用户的货币作为
Transaction
创建表单的初始值。但初始值永远不会呈现。

我的看法:

def create_transaction_view(request):
    if request.method == "POST":
        form = NewInvoiceForm(
            request.POST,
            instance=request.user
        )
        if form.is_valid():
            new_invoice = Transaction(**form.cleaned_data)
            # retrieving user's currency preference for further converting if income is different from base currency
            user_currency = request.user.config.currency
            # performing currency conversion to maintain consistent data for statistic and analyse
            if user_currency != new_invoice.currency:
                transaction_converted_value = CurrencyExchangeManager.currency_converter(
                    value=new_invoice.value,
                    exchange_to=user_currency,
                    base=new_invoice.currency
                )
                new_invoice.value = transaction_converted_value
                new_invoice.currency = user_currency
            new_invoice.save()
        return HttpResponseRedirect(request.META.get('HTTP_REFERER', "/"))

我总是将“破折号”字段作为初始选择。 感谢有关此主题的任何建议。

django django-forms
1个回答
0
投票

您的代码大部分是正确的,但您需要检查它是否正确处理您的表单的

GET
POST
请求。

这里

request.method == "POST"
条件对于处理表单提交至关重要,您可以在其中处理用户发送的数据。该块是验证和处理表单数据的地方。

但是当用户提交表单时,此块负责处理提交的数据,验证数据,然后执行必要的操作,例如保存数据或进行其他处理,例如在您的情况下进行货币转换。 到目前为止,您的代码是正确的。

但是对于初始表单渲染,特别是对于

GET
请求,表单应该使用代码中缺少的初始值进行设置。

当用户首次请求表单时,通常是一个

GET
请求。在这种情况下,您应该为表单字段提供初始值。在您的应用程序中,这意味着将货币字段的初始值设置为用户的首选货币。您可以使用视图函数的
else
块来完成此操作,该块处理 GET 请求,如下所示:

else:
    user_currency = request.user.config.currency
    form = NewInvoiceForm(initial={'currency': user_currency})

该表单使用货币的初始值进行实例化,确保当用户访问表单以创建新交易时,他们会看到预先选择的首选货币。

这是您在

views.py
中需要的
create_transaction_view
方法

的完整更新代码
def create_transaction_view(request):
    if request.method == "POST":
        form = NewInvoiceForm(
            request.POST,
            instance=request.user
        )
        if form.is_valid():
            new_invoice = Transaction(**form.cleaned_data)
            # retrieving user's currency preference for further converting if income is different from base currency
            user_currency = request.user.config.currency
            # performing currency conversion to maintain consistent data for statistic and analyse
            if user_currency != new_invoice.currency:
                transaction_converted_value = CurrencyExchangeManager.currency_converter(
                    value=new_invoice.value,
                    exchange_to=user_currency,
                    base=new_invoice.currency
                )
                new_invoice.value = transaction_converted_value
                new_invoice.currency = user_currency
            new_invoice.save()
     else:
          user_currency = request.user.config.currency
          form = NewInvoiceForm(initial={'currency': user_currency})

     return HttpResponseRedirect(request.META.get('HTTP_REFERER', "/"))
© www.soinside.com 2019 - 2024. All rights reserved.