Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.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
Python Django代理模型和ForeignKey_Python_Django_Django Models - Fatal编程技术网

Python Django代理模型和ForeignKey

Python Django代理模型和ForeignKey,python,django,django-models,Python,Django,Django Models,如何使entry.category成为CategoryProxy的实例?有关详细信息,请参见代码: class Category(models.Model): pass class Entry(models.Model): category = models.ForeignKey(Category) class EntryProxy(Entry): class Meta: proxy = True class CategoryProxy(Category):

如何使entry.category成为CategoryProxy的实例?有关详细信息,请参见代码:

class Category(models.Model): pass

class Entry(models.Model):
    category = models.ForeignKey(Category)

class EntryProxy(Entry):
    class Meta:
        proxy = True

class CategoryProxy(Category):
    class Meta:
        proxy = True

entry = EntryProxy.objects.get(pk=1)
entry.category # !!! I want CategoryProxy instance here
从Category转换到CategoryProxy也可以,但我不太熟悉ORM内部,无法正确复制内部状态

编辑。
原因:我向CategoryProxy添加了方法,并希望使用他:

EntryProxy.objects.get(pk=1).category.method_at_category_proxy()
编辑2。 目前我是这样实现的:

EntryProxy._meta.get_field_by_name('category')[0].rel.to = CategoryProxy
class EntryProxy(Entry):
    @property
    def category(self):
        category = super(EntryProxy, self).category
        new_inst = EntryProxy()
        for attr in [f.attname for f in category.__class__._meta.fields] + ['_state']:
            setattr(new_inst, attr, getattr(category, attr))
        return new_inst

但是看起来很糟糕…

在EntryProxy上定义一个属性
category
,该属性通过其id查找CategoryProxy:

class EntryProxy(Entry):
    @property
    def category(self):
        cid = super(EntryProxy, self).category.id
        return CategoryProxy.objects.get(id=cid)

    class Meta:
        proxy = True

要在不命中数据库的情况下从模型类切换到代理类,请执行以下操作:

class EntryProxy(Entry):
    @property
    def category(self):
        new_inst = EntryProxy()
        new_inst.__dict__ = super(EntryProxy, self).category.__dict__
        return new_inst
class CategoryProxy(Category):
    @property
    def entry_set(self):
        qs = super(CategoryProxy, self).entry_set
        qs.model = EntryProxy
        return qs
编辑:上面的代码片段似乎不适用于django 1.4

自django 1.4以来,我手动获取所有值字段,如下所示:

EntryProxy._meta.get_field_by_name('category')[0].rel.to = CategoryProxy
class EntryProxy(Entry):
    @property
    def category(self):
        category = super(EntryProxy, self).category
        new_inst = EntryProxy()
        for attr in [f.attname for f in category.__class__._meta.fields] + ['_state']:
            setattr(new_inst, attr, getattr(category, attr))
        return new_inst
要在不命中数据库的情况下从查询集切换到子代理类,请执行以下操作:

class EntryProxy(Entry):
    @property
    def category(self):
        new_inst = EntryProxy()
        new_inst.__dict__ = super(EntryProxy, self).category.__dict__
        return new_inst
class CategoryProxy(Category):
    @property
    def entry_set(self):
        qs = super(CategoryProxy, self).entry_set
        qs.model = EntryProxy
        return qs

稍加修改Bernd Petersohn的回答,我们得出:

class EntryProxy(Entry):
    @property
    def category(self):
        return CategoryProxy.objects.get(id=self.category_id)

对于数据库来说,这应该更经济。对于附加的改进,您可以在第一次调用该方法时设置私有属性(
self.\u category
),然后在所有后续时间返回该属性。

这是一个开放的Django问题:

定义代理模型后,可以通过重置相关字段来解决此问题:

EntryProxy.add_to_class('category', CategoryProxy)

这个问题已经有了一个公认的答案,但我想为任何可能来搜索的人发布这个问题

您可以在运行时使用新字段修补模型,以便关系按预期工作。这里可以看到一个完整的例子-


目前的解决方案(包括公认的解决方案)都不能与Django 2.0一起使用


在Matt Schinckel的基础上,这里有一个。

您为什么要这样做?我在CategoryProxy中添加了方法,并希望像EntryProxy.objects.get(pk=1.category.method_at_category_proxy()一样使用它,这意味着每次类别查找都会命中数据库!如果我们在循环呢?+1+1谢谢!你是怎么想到这个的?我很好奇你是否有一篇博文或其他东西详细解释QuerySet.model是如何工作的……第一次是在stackoverflow中找到的,第二次是在bpython shell测试中找到的。很高兴看到它有所帮助。