Django代理模型返回错误的ContentType

whlutmcx  于 2023-10-21  发布在  Go
关注(0)|答案(1)|浏览(100)

假设我们有一个模型Company和子类型Client,如下所示:

class Company(models.Model):
    name = models.CharField(max_length=100)
    related_companies = models.ManyToManyField('self', symmetrical=True)
    is_customer = models.BooleanField(default=False)

class ClientManager(Manager):
    def get_queryset(self):
        return QuerySet(self.model, using=self._db).filter(is_customer=True)

class Client(Company):
    objects = ClientManager()

    class Meta:
        proxy = True

接下来进入CLI,创建一个示例并获取其内容类型

from django.contrib.contenttypes.models import ContentType

In[38]: company = Company.objects.create(name='test', is_customer=True)

In [39]: ContentType.objects.get_for_model(company)
Out[39]: <ContentType: contacts | company>

它返回公司类的具体模型。到目前为止还不错。
接下来,根据文档,以下应该返回Client content-type。

In [40]: ContentType.objects.get_for_model(company, for_concrete_model=False)
Out[40]: <ContentType: contacts | company>

但事实并非如此。我还在接收混凝土模型公司而不是客户
你看到我的错误了吗?

eaf3rand

eaf3rand1#

如果您期望Client作为输出,则get_for_model是为错误的对象完成的。

In [40]: ContentType.objects.get_for_model(company, for_concrete_model=False)   
Out[40]: <ContentType: contacts | company>

在这段代码中,您请求company变量的ContentType,这是一个Company对象。此内容类型应返回Company
如果你遵循这个the link mentioned in my comment,你会看到,当你对这行代码做一个小小的修改时:

ContentType.objects.get_for_model(company, for_concrete_model=False)

company更改为Client对象,这样就可以得到如下内容

client = Client.objects.create(name='test', is_customer=True)
ContentType.objects.get_for_model(client , for_concrete_model=False)

返回的将是客户端内容类型。
The django docs声明如下
get_for_model(model,for_concrete_model=True)
获取模型类或模型示例,并返回表示该模型的ContentType示例。for_concrete_model=False允许获取代理模型的ContentType。
这意味着,如果您设置for_concrete_model=True并执行get_for_model(client),您将获得Company内容类型,因为客户端模型是公司模型的代理模型。

相关问题