到目前为止,关于SO的所有其他答案都以完全相同的方式回答:构造你的元类然后继承那些元类的"加入"版本,即
class M_A(type): pass
class M_B(type): pass
class A(metaclass=M_A): pass
class B(metaclass=M_B): pass
class M_C(M_A, M_B): pass
class C:(A, B, metaclass=M_C): pass
Run Code Online (Sandbox Code Playgroud)
但我不知道这些人住在哪个世界,他们在哪里构建自己的元类!显然,一个人会使用其他库中的类,除非你对元编程有一个完美的处理,你怎么知道你是否可以覆盖一个类的元类?(显然我还没有处理它们).
我的问题是:
class InterfaceToTransactions(ABC):
def account(self):
return None
...
class Category(PolymorphicModel, InterfaceToTransactions):
def account(self):
return self.source_account
...
class Income(TimeStampedModel, InterfaceToTransactions):
def account(self):
return self.destination_account
...
Run Code Online (Sandbox Code Playgroud)
这当然给了我错误:"元类冲突:派生类的元类必须是其所有基础的元类的(非严格)子类" 我已经尝试了上面给出的解决方案的许多变体,以下是不工作,给出同样的错误.
class InterfaceToTransactionsIntermediaryMeta(type(PolymorphicModel), type(InterfaceToTransactions)):
pass
class Category(PolymorphicModel, InterfaceToTransactions):
__metaclass__ = InterfaceToTransactionsIntermediaryMeta
...
Run Code Online (Sandbox Code Playgroud)
也没有把任何东西放在Meta函数中.我已经阅读了关于这个主题的每一个其他问题,请不要简单地将其标记为重复.
-------------------在接受解决方案后的1/8/18编辑-------
奇怪的是,如果我尝试使用这个新配置(我接受的那个)进行迁移,它会再次开始给出元类错误,但它仍然可以在运行时运行.如果我注释掉元类部件然后makemigrations并迁移,它会成功完成,但是每次迁移后我都必须把它放回去.
使用Polymorphic和其他插件玩一下我想知道如何防止某些基类字段显示在子管理界面的表单内部.为我的子类创建此adminy.py:
from django.contrib import admin
from .models import *
from partsmanagement.models import Part
from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin
admin.site.register(Book)
class BookAdmin(PolymorphicChildModelAdmin):
base_model = Part
Run Code Online (Sandbox Code Playgroud)
以及基本模型的admin.py:
# -*- coding: utf-8 -*-
from django.contrib import admin
from .models import *
from polymorphic.admin import PolymorphicParentModelAdmin, PolymorphicChildModelAdmin
from bookcollection.models import Book
from bookcollection.admin import BookAdmin
admin.site.register(Part)
class PartAdmin(PolymorphicParentModelAdmin):
base_model = 'Part'
child_models = (
(Book, BookAdmin),
)
Run Code Online (Sandbox Code Playgroud)
现在,admin中的表单显示了base和child类的所有文件.我试图为子类添加exclude = list()但这不起作用(没有更改).
我有一个普通的 Django 模型,它与 django 多态模型有外键关系。
让我们将第一个PlainModel具有contentForeignKey 字段的字段调用为具有子类型和 的多态Content模型(简化示例)。VideoAudio
现在我想查询PlainModel引用Video.
问题是我找到的所有文档都是关于直接通过多态模型本身进行过滤的。所以在这个例子中类似的东西Content.objects.instance_of(Video)。但我需要PlainModel's,所以它需要看起来像PlainModel.objects.filter(content__instance_of=Video)。我尝试了很多变体,但找不到任何有效的方法。
在他们使用的文档中Q(instance_of=ModelB),但这不适用于关系 as Q(content__instance_of=ModelB)。它给出了类似“无法查询“x”:必须是“y”实例”的错误。即使有翻译调用,我猜也是因为 PlainModel 不具有多态性。
我有一个临时 hack,可以polymorphic_ctype使用常规 django 过滤器(例如 )直接在字段上进行过滤PlainModel.objects.filter(content__polymorphic_ctype_id=my_content_type_id),但这不处理子类。例如:ExtendedVideo查找时找不到Video,因为它会有不同的 ContentType id。
我可以解决这个问题并保留允许的子类型列表或解析类型层次结构以获取过滤器的更多内容类型,但这似乎重复了 django-polymorphic 的功能。
这是我第一次尝试“PolymorphicModel”,也许我做错了什么,或者我正在尝试做一些不受支持的事情。有办法解决这个问题吗?
我的简化模型:
from django.polymorphic import PolymorphicModel
class Question(PolymorphicModel):
description = models.TextField(default='')
compound_question = models.ForeignKey('CompoundQuestion',
on_delete=models.CASCADE,
blank=True,
null=True,
related_name='sub_questions')
bonus_question = models.OneToOneField('BonusQuestion',
on_delete=models.CASCADE,
blank=True,
null=True,
related_name='question')
class SimpleQuestion(Question):
pass
class CompoundQuestion(Question):
pass
class BonusQuestion(Question):
pass
Run Code Online (Sandbox Code Playgroud)
如果我创建必要的实例,
compound_q = CompoundQuestion()
compound_q.save()
simple_q2 = SimpleQuestion(compound_question=compound_q)
simple_q2.save()
bonus_q = BonusQuestion(compound_question=compound_q)
bonus_q.save()
simple_q1 = SimpleQuestion(bonus_question=bonus_q)
simple_q1.save()
Run Code Online (Sandbox Code Playgroud)
所以最后我得到:
compound_q.sub_questions.all()
>>> <PolymorphicQuerySet [<BonusQuestion: BonusQuestion object (5)>, <SimpleQuestion: SimpleQuestion object (8)>]>
Run Code Online (Sandbox Code Playgroud)
完成后compound_q.delete()
我得到:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File ".../Python/Django/env/lib/python3.6/site-packages/django/db/models/base.py", line …Run Code Online (Sandbox Code Playgroud) 使用该django-polymorpic模块是一种简化对象继承的好方法,其中许多子类都继承自基类,并与基类共享多个属性。但是,虽然几乎所有东西都像普通对象一样工作,但擦除.pk和调用的方法save()不起作用?我试过了:
o = MyPolymorphicSubTable.objects.first()
print(o.pk) # 22
o.pk = None
o.save()
print(o.pk) # still 22 -- still the same object
Run Code Online (Sandbox Code Playgroud)
还尝试过:
print(o.id) # 22
o.id = None
o.save()
print(o.id) # still 22
Run Code Online (Sandbox Code Playgroud)
有人有答案吗?
我有如下模型结构:
class MyObject(PolymorphicModel):
group = models.ForeignKey(Group)
class Group(PolymorphicModel):
pass
class SpecialGroup(Group):
pass
Run Code Online (Sandbox Code Playgroud)
现在,我想选择所有MyObjects,哪个组是SpecialGroup类型.
是否可以使用QuerySet API实现它,而无需运行原始SQL?我想出的唯一可行解决方案是使用.extra()运行额外的"select"SQL查询.
提前谢谢,干杯!