首页 > 解决方案 > 如何为 django 模型字段生成选择元组以在表单中使用

问题描述

尝试基于另一个模型创建选择字段

我希望我的选择被映射为username: first_name + last_name

当我尝试username: last_name它确实有效

我尝试做这样的事情(注意,我正在添加 user_choices 和 Choices=user_choices。在我进行这些更改之前,该模型已经存在。)

这有效:

he_user_choices = tuple(User.objects.values_list('username', 'last_name'))

这是我的 models.py 的样子:

from django.contrib.auth.models import User

owner_choices = tuple(User.objects.values_list('username', 'first_name' + 'last_name'))


class ErrorEvent(models.Model):
    """Error Event Submissions"""
    event_id = models.BigAutoField(primary_key=True)
    owner = models.IntegerField(verbose_name="Owner", blank=True, choices=owner_choices)

这是我的forms.py

from django import forms
from .models import ErrorEvent


class ErrorEventForm(forms.ModelForm):

    class Meta:
        model = ErrorEvent
        # fields =
        exclude = ['event_id']
        widgets = {
            'owner': forms.Select(),
        }

目前 owner_choices 不起作用,我收到一条错误消息:

django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.

关于我还能尝试什么,或者我将如何解决我的问题的任何建议?

先感谢您!

标签: pythondjangodjango-modelsdjango-forms

解决方案


请不要使用anIntegerField来引用对象。AForeignKey将检查引用完整性,此外它使 Django ORM 更具表现力。

因此,您可以通过以下方式实现:

from django.conf import settings

class ErrorEvent(models.Model):
    event_id = models.BigAutoField(primary_key=True)
    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        verbose_name='Owner',
        blank=True,
        null=True
    )

这将与自动查询数据库以呈现选项的ModelChoiceField[Django-doc]一起使用。这也意味着如果您添加一个新的User,创建一个新的ErrorEvent可以链接到该用户,因为它每次都User从数据库中请求 s。

您可以对 进行子类化ModelChoiceField以指定如何显示选项,例如:

from django.forms import ModelChoiceField

class MyUserModelChoiceField(ModelChoiceField):

    def label_from_instance(self, obj):
        return f'{obj.username} ({obj.firstname} {obj.lastname})'

然后我们可以在表单中使用它:

class ErrorEventForm(forms.ModelForm):
    owner = MyUserModelChoiceField(queryset=User.objects.all())

    class Meta:
        model = ErrorEvent
        # fields =
        exclude = ['event_id']
        widgets = {
            'owner': forms.Select(),
        }

推荐阅读