【问题标题】:How to use one model as source for 'choices' in another model?如何使用一个模型作为另一个模型中“选择”的来源?
【发布时间】:2018-12-03 19:32:23
【问题描述】:

我有 3 个模型:User、UserProfile 和 Programme。用户持有所有用户的姓名;

class User(AbstractUser):
    first_name = model.Charfield(...)
    last_name = model.Charfield(...)
    ...

UserProfile 包含与每个用户相关的属性(例如,销售经理(sm)、项目经理(pm)、交付经理(dm)等。

class UserProfile(model.Model):
    user = model.ForeignKey(User, on_delete...)
    sm = model.BooleanField(default = False, editable=True...)
    pm = model.BooleanField(default = False, editable=True...)
    dm = model.BooleanField(default = False, editable=True...)

用户可以具有 UserProfile 属性的任意组合。例如: 用户 1:sm 用户 2:sm,pm 用户 3:dm 用户 4:sm,dm ...

Program 中的每个程序都必须为每个 sm、pm 和 dm 分配一个用户,所以我的挑战是找到一种方法来为每个 sm、pm 和 dm 生成一个“选择”列表,限制为具有适当属性的用户。

class Programme(model.Models):
    programme_name = models.Charfield(...)
    AND ESSENTIALLY:
    sm = only users with userprofile.sm = True
    pm = only users with userprofile.pm = True
    dm = only users with userprofile.dm = True

我尝试向 UserProfile 添加一个函数,然后在 Programme 中引用它:

UserProfile(model.Models):
....

def get_pm(self):
    pm_list = []
    pm = UserProfile.objects.filter(pm=True)
    for i in pm:
        pm_list.append(i.user.last_name)
        return pm_list

在节目中:

Programme(model.Models):
    pm = models.Charfield(choices=UserProfile.get_pm, ...

但这会产生错误:“选择”必须是可迭代的(例如,列表或元组)。

同样,我尝试将相同的函数添加到 Programmes/models.py,但这会产生相同的错误。

我知道我遗漏了显而易见的内容,但感谢所有帮助。

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    您不需要为用户配置文件创建单独的模型:

     class User(AbstractUser):
         first_name = model.Charfield(...)
         last_name = model.Charfield(...)
         POST_CHOICES = (
           ('sm', ("sm")),
           ('sm', ("pm")),
           ('sm', ("dm")),
           )
         post=models.CharField(choices=POST_CHOICES,max_length=150, blank=True)
         programme_name = models.Charfield(max_length=150, blank=True)
    

    您可以过滤掉属于 sm 的用户,例如使用过滤查询,或者您可以为此使用模型管理器

    【讨论】:

    • 这种方法适用于静态选择。我的挑战是用户和用户配置文件的数量会经常变化,所以选择也​​必须经常变化。事实上,对于同一日期的程序,有必要过滤掉已经提交给程序/日期对的用户/用户配置文件。
    【解决方案2】:

    好吧,经过大量荒谬的阅读、反复试验后,出现了一个简单的解决方案:使用适当的查询简单地覆盖表单字段 -

    class ProgrammeCreateForm(forms.ModelForm):
    class Meta:
        model = Programme
        fields = [
            'name', 'company', 'status', 'pm', 'sm', 'dm', 'idm','start_date', 'end_date', 'delivery_type'
        ]
    
    def __init__(self, *args, **kwargs):
        super(ProgrammeCreateForm, self).__init__(*args, **kwargs)
        sm_choices = UserProfile.objects.filter(sm=True)
        pm_choices = UserProfile.objects.filter(pm=True)
        dm_choices = UserProfile.objects.filter(dm=True)
        idm_choices = UserProfile.objects.filter(idm=True)
        self.fields['sm'] = forms.ModelChoiceField(queryset=sm_choices)
        self.fields['pm'] = forms.ModelChoiceField(queryset=pm_choices)
        self.fields['dm'] = forms.ModelChoiceField(queryset=dm_choices)
        self.fields['idm'] = forms.ModelChoiceField(queryset=idm_choices)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 2018-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-12
      • 1970-01-01
      相关资源
      最近更新 更多