我想知道哪些模型是一个模型的子模型,以检索它们的on_delete
属性。如我所知,如下所示,如果我们有ownerModel
,它是childModel1
和check1Model
的父模型:
import uuid
from django.db import models
class ownerModel(models.Model):
ownerId = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False, blank=True)
class check1Model(models.Model):
checkId = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False, blank=True)
owner=models.ForeignKey(ownerModel,on_delete=models.CASCADE)
class childModel1(models.Model):
childId = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False, blank=True)
check2=models.ForeignKey(ownerModel,on_delete=models.CASCADE)
然后我们可以用下面这样的代码得到哪些模型是ownerModel
的子模型:
class myView(views.APIView):
def get(self, request, format=None):
for f in ownerModel._meta.get_fields():
if 'field' in f.__dict__.keys():
print('***childModels***')
print(f.__dict__)
print()
return Response({'0000'}, status=status.HTTP_200_OK)
我的意思是通过检查field
键是否在ownerModel._meta.get_fields()
项中的__dict__.keys()
中。
当然,在这里我们可以得到更多关于儿童模特的信息:
***childModels***
{'field': <django.db.models.fields.related.ForeignKey: owner>, 'model': <class 'Users.models.ownerModel'>, 'related_name': None, 'related_query_name': None, 'limit_choices_to': {}, 'parent_link': False, 'on_delete': <function
CASCADE at 0x00000286550848B0>, 'symmetrical': False, 'multiple': True, 'field_name': 'ownerId', 'related_model': <class 'Users.models.check1Model'>, 'hidden': False}
***childModels***
{'field': <django.db.models.fields.related.ForeignKey: check2>, 'model': <class 'Users.models.ownerModel'>, 'related_name': None, 'related_query_name': None, 'limit_choices_to': {}, 'parent_link': False, 'on_delete': <function CASCADE at 0x00000286550848B0>, 'symmetrical': False, 'multiple': True, 'field_name': 'ownerId', 'related_model': <class 'Users.models.childModel1'>, 'hidden': False}
因此,我发现这两个条件是必要的,以获得儿童模型信息:
1.在子模型中,确保使用如下行设置子关系:
models.ForeignKey(ownerModel,on_delete=models.CASCADE)
1.如说“如果field
键是在__dict__.keys()
项中的ownerModel._meta.get_fields()
项中“则得到子项信息。
但问题是,在某些情况下,我无法从父模型中获得子模型的信息。
1.这让我想知道这2个条件是否足以发现哪些模特是模特的孩子?
1.是否有其他类似的方法来获取哪些模型是模型的子模型?
顺便说一下,我也想拥有on_delete
,拥有on_delete
是我使用_meta.get_fields()
而不是_meta.fields
的唯一原因,因为_meta.fields
不提供on_delete
属性。
这是my code,如果你想看一下的话。注意,在完整的答案中,我还想知道是什么造成了问题。所以在这个例子中,__dict__.keys()
不提供在它们的键中没有field
的项目(不提供子模型细节)。因为通常这两个条件提供子模型细节。所以稍后我可以在所有代码中获得子模型细节。
问题是,即使有for f in ownerModel._meta.get_fields(include_hidden=True)
,并且没有任何进一步的if
,s也不会在此项目中检索包含on_delete
属性的行。但在其他项目中,ownerModel._meta.get_fields()
提供了这些属性。我不知道有时ownerModel._meta.get_fields()
提供这些关系信息而其他时候不提供的原因是什么。
3条答案
按热度按时间2izufjch1#
可以使用
Model._meta.related_objects
查找模型的子级您可以使用这个类别做为模型的
mro
。wgeznvg72#
更新
在进一步调查评论后,发现问题是模型没有在
models
子模块中定义。如Django文档所述:定义好模型后,你需要告诉Django你要使用这些模型。编辑你的设置文件,修改INSTALLED_APPS设置,添加包含models.py的模块名称。
这个要求也可以在处理模型检测的Django源代码中得到确认:
原始答案
使用
__dict__
并没有明显的原因。但是,__dict__
并不适合这种用法。例如,这是not reliable,没有理由在hasattr()
上使用它。下面是一些
__dict__
可能出错的示例:您可以改用
hasattr()
:然而,检查
field
属性的存在似乎不是确定字段是否是向后关系的可靠解决方案。我更推荐依赖one_to_one
和one_to_many
属性,对于非关系字段为None
,对于关系字段为True/False
:我还在条件中包含了
hasattr(f, 'on_delete')
,以排除在ownerModel
中定义的OneToOneField
关系。gmol16393#
如果你想检索这个模型的反向关系,你可以使用
ownerModel._meta.related_objects
。但是这是Django私有API的一部分,没有正式的文档/支持。你可以在源代码中找到文档。返回指向当前模型的所有相关对象。相关对象可以来自一对一、一对多或多对多字段关系类型。
仅由Django自己使用的私有API;
get_fields()
与字段属性的过滤相结合是用于获取此字段列表的公共API。您也可以通过使用公共API过滤
get_fields()
来获得类似的结果:此解决方案还为您提供了在
ownerModel
中定义的多对多关系,如果您需要多对多关系,这可能是预期的。要排除所有多对多关系,只需将它们从条件中删除:一种严格地只获取向后关系(即,移除在
ownerModel
中定义的多对多和一对一关系)的方法可以是测试ForeignObjectRel
在字段的层次结构中的存在。如果您想要显示
on_delete
属性的值,可以将结果限制为一对一和一对多字段。