【问题标题】:Django: self referential foreign key with choice listDjango:带有选择列表的自引用外键
【发布时间】:2017-04-18 05:56:24
【问题描述】:

我的模型定义了一个员工,该员工有姓名、ID、工作和经理。我希望能够指定可以列为另一个员工经理的员工选择列表(类似于工作字段)。为此,我包括了

class Employee(models.Model):
    EXECUTIVE = 'EXC'
    SALESMAN = 'SAL'
    ENGINEER = 'ENG'
    CLERK = 'CLK'
    JOBS = (
        (EXECUTIVE, 'Executive'),
        (SALESMAN, 'Salesman'),
        (ENGINEER 'Engineer'),
        (CLERK, 'Clerk'),
    )
    employee_id = models.CharField(max_length = 5, primary_key=True)
    name = models.CharField(max_length=25)
    job = models.CharField(max_length=3, choices=JOBS) 
    is_manager = models.BooleanField(default=False)
    manager = models.ForeignKey('self', on_delete=models.PROTECT, null=True, choices=get_managers()) 

    def __str__(self):
        return self.name

还在我的 models.py 中定义了以下函数:

def get_managers():
    managers = []
    for manager in Employee.objects.filter(is_manager=True):
        managers.append((manager.employee_id, manager.name))
    return managers

我的问题是,当函数放在 Employee 类定义之前,我得到 NameError: name 'Employees' is not defined,而当放在 Employee 类定义之后,错误 NameError: name 'get_managers()' is not defined。我尝试将 get_managers() 放在类中并得到 `NameError: name 'get_managers()' is not defined

如果有更好的方法来完成同样的事情,我愿意接受建议。

【问题讨论】:

  • 您在使用任何表格吗?还是在 django admin 中?
  • 正如 Andrey 在他的回答中所建议的那样,这不应该是一个真正的 choice 字段,因为数据依赖。您应该将逻辑与模型分开。

标签: python django class django-models


【解决方案1】:

来自 Django 文档:http://docs.djangoproject.com/en/dev/ref/models/fields/#choices

最后,请注意,选择可以是任何可迭代的对象——不是 必须是列表或元组。这使您可以构建选择 动态的。但是,如果你发现自己的黑客选择是动态的, 您最好使用适当的数据库表和 外键。选择适用于变化不大的静态数据, 如果有的话。

【讨论】:

    【解决方案2】:

    如果你使用 django admin,你可以这样做。

    class EmployeeAdmin(admin.ModelAdmin):
        def get_form(self, request, obj=None, **kwargs):
            form = super(EmployeeAdmin, self).get_form(request, obj, **kwargs)
            form.base_fields['manager'].queryset = Employee.objects.filter(is_manager=True)
            return form
    

    然后在模型中

    manager = models.ForeignKey('self', on_delete=models.PROTECT, null=True, blank=True)
    

    admin.py

    admin.site.register(Employee, EmployeeAdmin)
    

    【讨论】:

      猜你喜欢
      • 2021-09-03
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 2013-02-23
      • 2021-08-09
      • 2021-06-02
      • 2012-11-26
      相关资源
      最近更新 更多