我有一个模型“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', "/"))
我总是将“破折号”字段作为初始选择。 感谢有关此主题的任何建议。
您的代码大部分是正确的,但您需要检查它是否正确处理您的表单的
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', "/"))