代码之家  ›  专栏  ›  技术社区  ›  cethegeek

如何获取和/或将查询集条件保存到数据库?

  •  15
  • cethegeek  · 技术社区  · 15 年前

    我想将一个查询集条件保存到数据库以便重用。

    所以,如果我有这样一个查询集:

    Client.objects.filter(state='AL') 
    
    # I'm simplifying the problem for readability. In reality I could have 
    # a very complex queryset, with multiple filters, excludes and even Q() objects.
    

    我想将查询集的结果(即状态字段与“al”匹配的单个客户机记录)保存到数据库,而不是保存到查询集本身(即筛选客户机模型时使用的条件)。

    最终的目标是拥有一个“保存的过滤器”,它可以从数据库中读取并由多个Django应用程序使用。

    起初我以为我可以序列化查询集并保存它。但是序列化一个查询集实际上会执行这个查询——然后在序列化时,我得到了阿拉巴马州的一个静态客户列表。我希望列表是动态的(即每次从数据库中读取查询集时,它都应该执行并检索阿拉巴马州最新的客户端列表)。


    编辑:或者,是否可以获取应用于查询集的筛选器列表?

    类似:

    qs = Client.objects.filter(state='AL')
    filters = qs.getFilters()
    print filters
    
    { 'state': 'AL' }
    
    5 回复  |  直到 11 年前
        1
  •  15
  •   gregoltsov naw    11 年前

    您可以按照JCD所说的那样做,存储SQL。

    您还可以存储条件。

    In [44]: q=Q( Q(content_type__model="User") | Q(content_type__model="Group"),content_type__app_label="auth")
    
    In [45]: c={'name__startswith':'Can add'}
    
    In [46]: Permission.objects.filter(q).filter(**c)
    Out[46]: [<Permission: auth | group | Can add group>, <Permission: auth | user | Can add user>]
    
    In [48]: q2=Q( Q(content_type__model="User") | Q(content_type__model="Group"),content_type__app_label="auth", name__startswith='Can add')
    
    In [49]: Permission.objects.filter(q2)
    Out[49]: [<Permission: auth | group | Can add group>, <Permission: auth | user | Can add user>]
    

    在这个例子中,您可以看到条件是对象 c q (尽管它们可以连接到一个对象中, q2 )然后可以序列化这些对象,并将它们作为字符串存储在数据库中。

    --编辑——

    如果需要在单个数据库记录上具有所有条件,可以将它们存储在字典中。

    {'filter_conditions': (cond_1, cond_2, cond_3), 'exclude_conditions': (cond_4, cond_5)} 
    

    然后将字典序列化。

        2
  •  4
  •   jcdyer Anand S Kumar    15 年前

    您可以使用查询集的 _as_sql() 方法。该方法将数据库连接作为参数,因此可以执行以下操作:

    from app.models import MyModel
    from django.db import connection
    
    qs = MyModel.filter(pk__gt=56, published_date__lt=datetime.now())
    store_query(qs._as_sql(connection))
    
        3
  •  3
  •   denz    13 年前
        4
  •  3
  •   guettli    12 年前

    可以pickle查询对象(而不是queryset):

    >>> import pickle
    >>> query = pickle.loads(s)     # Assuming 's' is the pickled string.
    >>> qs = MyModel.objects.all()
    >>> qs.query = query            # Restore the original 'query'.
    

    Docs: https://docs.djangoproject.com/en/dev/ref/models/querysets/#pickling-querysets

    但是:您可以在不同版本之间共享pickle

        5
  •  1
  •   Saff    15 年前

    您可以创建自己的模型来存储查询。 第一个字段可以包含FK到 ContentTypes 第二个字段可以只是查询等的文本字段。

    然后你可以用 Q object 为模型设置queryset。

    推荐文章