Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 外键中的许多模型_Django_Django Models - Fatal编程技术网

Django 外键中的许多模型

Django 外键中的许多模型,django,django-models,Django,Django Models,假设我有一个模型,雇员: 雇员 姓名:查菲尔德 电子邮件:EmailField 类型:外键 问题在于类型字段。我希望外键能够是几种不同类型的型号。例如,一个用于软件开发人员,另一个用于看门人,等等 我可以通过为所有类型设置外键字段,并将many设置为null来实现这一点,但这似乎很糟糕。这有意义吗 我怎样才能做到这一点?谢谢 有很多方法可以将这种多态性级别建模到这样的场景中 方案1-混凝土基础模型 包括一个employee_type字段,该字段指示正在使用的具体模型 类Employeemodel

假设我有一个模型,雇员:

雇员

姓名:查菲尔德 电子邮件:EmailField 类型:外键 问题在于类型字段。我希望外键能够是几种不同类型的型号。例如,一个用于软件开发人员,另一个用于看门人,等等

我可以通过为所有类型设置外键字段,并将many设置为null来实现这一点,但这似乎很糟糕。这有意义吗


我怎样才能做到这一点?谢谢

有很多方法可以将这种多态性级别建模到这样的场景中

方案1-混凝土基础模型

包括一个employee_type字段,该字段指示正在使用的具体模型

类Employeemodels。模型: 名称=型号。CharFieldmax_长度=50 email=models.CharFieldmax_length=80 员工类型=型号。CharFieldmax\u长度=20 门卫级员工: [...] 类软件工程师雇员: [...] 所有相互属性都可以存储在员工模型中

一旦一个具体的类软件工程师、看门人等被实例化,它将从其父类继承所有属性

通过设置和使用employee_类型,可以区分创建了哪个具体类

有关这方面的更多信息,请参见

[更新]

使用django信号,可以派生具体的类名,并将其与关联实例一起存储

signals.py

从django.db.models.signals导入预保存 def store_classnamesender,实例,**kwargs: instance.employee\u type=instance.\u类\u.\u名称__ 对于Employee中的子类。\uuuu子类\uuuuu: pre_save.connectstore_类名,sender=子类 这样可以确保每次都存储正确的标识符

现在,在您希望选择要使用的混凝土类类型的视图中,您可以在如下条件下继续使用它:

views.py

示例用法 employee=employee.objects.getid=1 如果employee.employee_type==“看门人”: employee=看门人.objects.getid=employee.id 或者通过使用模型名称和全局变量的查找动态地派生它

示例用法 从。模型导入* def get_类名称: cls=globals[classname] 返回cls employee=employee.objects.getid=1 具体\u员工=获取\u classemployee.employee\u类型 [...] 注意:更改父模型或子模型的名称时要小心,因为这会影响使用旧模型名称的历史记录。要解决此问题,请使用django的update或bulk_update函数将所有旧名称转换为新名称。更多信息是

选项2-django多态

使用名为django多态性的django包,这允许在查询父类时返回所有具体类

models.py

查询员工模型时,将返回以下内容

>>> Employee.objects.filter(id=1)
[ <Employee:         id 1, name "Joe Bloggs", email "example@example.com">,
  <SoftwareEngineer:  id 1, name "Joe Bloggs", email "example@example.com", predominant_programming_language "Python">,]

谢谢你的回复!如何将employee_type字段链接到门卫或软件工程师模型?谢谢@NGI没问题,希望答案编辑能解决您的问题。
>>> Employee.objects.filter(id=1)
[ <Employee:         id 1, name "Joe Bloggs", email "example@example.com">,
  <SoftwareEngineer:  id 1, name "Joe Bloggs", email "example@example.com", predominant_programming_language "Python">,]