Python 如何安全地从django models.Model类继承?
我有以下数据库结构:Python 如何安全地从django models.Model类继承?,python,django,database,django-models,django-views,Python,Django,Database,Django Models,Django Views,我有以下数据库结构: 类字(models.Model): 原始=型号.CharField(最大长度=40) translation=models.CharField(最大长度=40) 类动词(词): group=models.IntegerField(默认值=1) 在我看来,我需要首先创建一个Word对象,在确定其组(取决于Word.original)后,创建一个动词对象并保存它 从Word类继承并将对象另存为动词的最佳方法是什么 我尝试过几种解决方案: 1) 修改动词中的\uuuuu ini
类字(models.Model):
原始=型号.CharField(最大长度=40)
translation=models.CharField(最大长度=40)
类动词(词):
group=models.IntegerField(默认值=1)
在我看来,我需要首先创建一个Word
对象,在确定其组(取决于Word.original
)后,创建一个动词
对象并保存它
从Word
类继承并将对象另存为动词
的最佳方法是什么
我尝试过几种解决方案:
1) 修改动词
中的\uuuuu init\uuuu
方法:
类动词(词):
group=models.IntegerField(默认值=1)
定义初始化(自、基字):
self.original=base\u word.original
self.translation=base\u word.translation
这会导致很多错误,因为我正在重写django的内置\uuuu init\uuu
方法
2) 使用super()
类动词(词):
group=models.IntegerField(默认值=1)
定义初始化(自、基字):
super()。\uuuu init\uuuuu()
self.original=base\u word.original
self.translation=base\u word.translation
显然,这很有效:
base\u word=word()
新动词=动词(基本单词)
new_动词.save()
但有两个问题:
尝试查看django管理页面中的对象时会导致错误:
\uuuu init\uuuuu()接受2个位置参数,但给出了9个
这仍然是太多的代码,感觉不对。我还需要写下:
self.original=base\u word.original
self.translation=base\u word.translation
在每个子类中。这只是一个例子。在实际项目中,我有更多的领域。我想有一个更优雅的解决办法 重写\uuuu init\uuuu
不是正确的方法。Django模型执行大量的幕后工作,重写\uuuu init\uuuu
可能会与这些工作冲突,除非您通过以下规则以安全的方式执行:
- 不要更改
\uuuu init\uuuu
的签名——这意味着您不应该更改方法接受的参数
- 在调用
super()之后执行自定义\uuuuuuuu init\uuuuuu>逻辑
在这种特殊情况下,您可以使用
动词=“V”
名词=“N”
# ...
单词类型选择=(
(动词,“动词”),
(名词,“名词”),
# ...
)
类词(models.Model):
原始=型号.CharField(最大长度=40)
translation=models.CharField(最大长度=40)
WORD_TYPE=”“#这在子类中被重写
word_type=models.CharField(
最大长度=1,
空白=真,
editable=False,#因此无法通过管理员编辑单词类型。
选项=单词类型选项,
default=WORD_TYPE,#默认为空字符串
)
定义初始化(self,*args,**kwargs):
#注意:我不是100%肯定这是必需的,但因为我们不是
#更改_init _方法的签名,执行
#单词类型字段的赋值是安全的。
super()
self.word\u type=self.word\u type
定义(自我):
返回原始状态
def保存(自身、*args、**kwargs):
#在save方法中,我们可以强制子类自赋值
#他们的词类。
如果不是self.word\u类型:
self.word\u type=self.word\u type
super().save(*args,**kwargs)
类WordTypeManager(models.Manager):
“”“此管理器类筛选模型的查询集,以便只有
返回特定的单词类型。
"""
定义初始化(self,word类型,*args,**kwargs):
“”“管理器已使用代理模型的'word\u type'初始化。”“”
self.\u word\u type=word\u type
super()
def get_queryset(自我):
return super().get\u queryset().filter(word\u type=self.\u word\u type)
类动词(词):
#在这里,我们可以强制使用这个代理模型的单词类型,并设置默认值
#管理器仅筛选动词。
单词类型=动词
objects=WordTypeManager(WORD\u类型)
类元:
proxy=True
类名词(词):
单词类型=名词
objects=WordTypeManager(WORD\u类型)
类元:
proxy=True
现在,我们可以将不同的单词类型视为单独的模型,或者通过word
模型一起访问它们
>名词=名词.对象.创建(original=“name”,translation=“nombre”)
>>>动词=动词(original=“write”,translation=“escribir”)
>>>动词save()
#选择所有单词,而不考虑其单词类型
>>>Word.objects.values\u列表(“Word\u类型”、“原始”)
#根据使用的模型类选择单词类型
>>>名词.objects.all()
>>>动词.objects.all()
这也适用于admin.ModelAdmin
类
@admin.register(Word)
类WordAdmin(admin.ModelAdmin):
“”“这将显示所有单词,而不管它们的“单词类型”。”
列表显示=[“单词类型”、“原始”、“翻译”]
@管理员注册(名词)
类别管理(WordAdmin):
“”“这将只显示'Noun'实例,并从中继承任何其他配置。”
WordAdmin。
"""
为什么不将shift确定是否在表单中创建一个动词。请不要覆盖\uuuuu init\uuuuu
。django文档明确指出,强烈建议不要覆盖\uuuuu init\uuuuu
,尤其是不要更改\uuuuuu init\uuuu
的签名。我可以给出更多细节。词有4个子类:动词
,名词
,形容词
,代词
。他们有很多共同的领域,所以我把他们放在Word
中。首先,我完成了所有这些