我有一个‘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', "/"))

我总是得到一个‘破折号’字段作为初始 Select . 感谢您对此主题的任何建议.

推荐答案

您的代码大部分都是正确的,但您需要判断它是否为您的表单适当地处理了GETPOST请求.

这里request.method == "POST"条件是至关重要的处理表单提交,在那里你处理由用户发送的数据.这个块是验证和处理表单数据的地方.

但当用户提交表单时,这个块负责处理提交的数据,验证它,然后执行必要的操作,如保存数据或执行其他处理,如您的情况下的货币兑换.Till this point your code was correct.

但是对于初始表单呈现,特别是对于GET个请求,应该使用代码中缺少的初始值来设置表单.

当用户第一次请求表单时,通常是GET个请求.在这种情况下,您应该提供表单域的初始值.在您的应用程序中,这意味着将Currency字段的初始值设置为用户的首选货币.您可以通过使用view函数的else块来实现这一点,该函数如下处理GET请求:

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

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

这里是完整的更新代码,你需要在views.pycreate_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', "/"))

注意:您甚至可以通过在create_transaction_view函数的开头初始化这个user_currency = request.user.config.currency来稍微优化代码,这样我们就不需要在代码中重复这两次.我这样给你是为了让你理解.

Django相关问答推荐

如何在Django中获取标记<;输入>;的';值';属性?

我的Django终结点不访问HAS_OBJECT_PERMISSION方法

Django没有';t显示黄页

try 在 django 中发送验证邮箱,出现错误

Django 根据子级过滤父级

Django ImproperlyConfigured: AUTH_USER_MODEL指向尚未安装的模型'users.User'

`.objects` 属性在哪里添加到 Django 的 models.Model 类中的实例命名空间?

有谁知道是否可以将您的 Django Heroku 应用程序放到 App Store/Google Play 上?

Django 长时间运行带有线程/处理的异步任务

Django中的单表继承

UnicodeDecodeError:asciicodec can't decode byte 0xe0 in position 0: ordinal not in range(128)

ImportError:无法导入设置

带有消息判断的 Django/Python assertRaises

Django模型字段按变量

将 Django Rest Framework 与序列化程序一起使用时出现 AttributeError

django 我们可以在预取相关模型上 Select 一个字段吗?

Django - 安装 mysqlclient 错误:需要 mysqlclient 1.3.13 或更高版本;你有 0.9.3

Django admin:使字段在添加中可编辑但不可编辑

如何在 Django 中创建一个非空的 CharField?

Django:按位置排序,忽略 NULL