首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >django异构查询集代理模型

django异构查询集代理模型
EN

Stack Overflow用户
提问于 2010-10-12 08:33:55
回答 2查看 1.6K关注 0票数 3

我正在尝试弄清楚如何在Django中使用代理类。我希望接收一个查询集,其中每个对象都属于一个公共超类的代理类,这样我就可以运行具有相同名称的定制子类方法,并且我的控制器逻辑不需要知道或关心它使用的是哪种代理模型。我不想做的一件事是将信息存储在多个表中,因为我希望有统一的标识符,以便更容易地引用/管理。

我是django/python的新手,所以我很高兴听到替代的方法来完成我想要做的事情。

这就是我所拥有的:

代码语言:javascript
复制
TYPES = (
    ('aol','AOL'),
    ('yhoo','Yahoo'),
)

class SuperConnect(models.Model):
  name = models.CharField(max_length=90)
  type = models.CharField(max_length=45, choices = TYPES)
  connection_string = models.TextField(null=True)

class ConnectAOL(SuperConnect):
  class Meta:
    proxy = True

  def connect(self):
     conn_options = self.deconstruct_constring()
     # do special stuff to connect to AOL

  def deconstruct_constring(self):
     return pickle.loads(self.connection_string)

class ConnectYahoo(SuperConnect):
  class Meta:
    proxy = True

  def connect(self):
     conn_options = self.deconstruct_constring()
     # do special stuff to connect to Yahoo

  def deconstruct_constring(self):
     return pickle.loads(self.connection_string)

现在我想做的是:

代码语言:javascript
复制
connections = SuperConnect.objects.all()

for connection in connections:
  connection.connect()
  connection.dostuff

我环顾四周,发现了一些黑客,但他们看起来有问题,可能需要我去数据库为每个项目,以检索我可能已经有数据……

谁来救救我:)否则我将使用这个黑客:

代码语言:javascript
复制
class MixedQuerySet(QuerySet):
    def __getitem__(self, k):
        item = super(MixedQuerySet, self).__getitem__(k)
        if item.atype == 'aol':
            yield(ConnectAOL.objects.get(id=item.id))
        elif item.atype == 'yhoo':
            yield(ConnectYahoo.objects.get(id=item.id))
        else:
            raise NotImplementedError

    def __iter__(self):
        for item in super(MixedQuerySet, self).__iter__():
            if item.atype == 'aol':
                yield(ConnectAOL.objects.get(id=item.id))
            elif item.atype == 'yhoo':
                yield(ConnectYahoo.objects.get(id=item.id))
            else:
                raise NotImplementedError

class MixManager(models.Manager):
    def get_query_set(self):
        return MixedQuerySet(self.model)

TYPES = (
    ('aol','AOL'),
    ('yhoo','Yahoo'),
)

class SuperConnect(models.Model):
  name = models.CharField(max_length=90)
  atype = models.CharField(max_length=45, choices = TYPES)
  connection_string = models.TextField(null=True)
  objects = MixManager()

class ConnectAOL(SuperConnect):
  class Meta:
    proxy = True

  def connect(self):
     conn_options = self.deconstruct_constring()
     # do special stuff to connect to AOL

  def deconstruct_constring(self):
     return pickle.loads(self.connection_string)

class ConnectYahoo(SuperConnect):
  class Meta:
    proxy = True

  def connect(self):
     conn_options = self.deconstruct_constring()
     # do special stuff to connect to Yahoo

  def deconstruct_constring(self):
     return pickle.loads(self.connection_string)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-10-12 09:17:52

把所有的逻辑放在一个类里怎么样?如下所示:

代码语言:javascript
复制
def connect(self):
    return getattr(self, "connect_%s" % self.type)()

def connect_aol(self):
    pass # AOL stuff

def connect_yahoo(self):
    pass # Yahoo! stuff

最后,你有了你的type字段,你应该能够做大多数(如果不是全部)你可以用分离的代理类做的事情。

如果这种方法不能解决您的特定用例,请澄清。

票数 0
EN

Stack Overflow用户

发布于 2013-01-12 05:15:51

正如您在问题中提到的,您的解决方案的问题是它为每个对象生成一个SQL查询,而不是使用一个SQL in = (id1, id2)查询。代理模型不能包含额外的数据库字段,因此不需要额外的SQL查询。

相反,您可以使用__class__属性在SuperConnect.__init__中将SuperConnect对象转换为适当的类型:

代码语言:javascript
复制
class SuperConnect(models.Model):
    name = models.CharField(max_length=90)
    type = models.CharField(max_length=45, choices = TYPES)
    connection_string = models.TextField(null=True)

    def __init__(self, *args, **kwargs):
        super(SuperConnect, self).__init__(*args, **kwargs)
        if self.type == 'aol':
            self.__class__ = ConnectAOL
        elif self.type == 'yahoo':
            self.__class__ = ConnectYahoo

不需要自定义管理器或查询集,在初始化SuperConnect对象时设置正确的类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3910936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档