Django:从 G​​ET 请求生成查询集

发布于 2024-09-29 05:28:54 字数 565 浏览 4 评论 0原文

我有一个使用 GET 方法的 Django 表单设置。每个值对应于 Django 模型的属性。生成查询的最优雅的方式是什么?目前,这就是我在视图中所做的事情:

def search_items(request):
    if 'search_name' in request.GET:
        query_attributes = {}

        query_attributes['color'] = request.GET.get('color', '')
        if not query_attributes['color']: del query_attributes['color']

        query_attributes['shape'] = request.GET.get('shape', '')
        if not query_attributes['shape']: del query_attributes['shape']

        items = Items.objects.filter(**query_attributes)

但我很确定有更好的方法来解决它。

I have a Django form setup using GET method. Each value corresponds to attributes of a Django model. What would be the most elegant way to generate the query? Currently this is what I do in the view:

def search_items(request):
    if 'search_name' in request.GET:
        query_attributes = {}

        query_attributes['color'] = request.GET.get('color', '')
        if not query_attributes['color']: del query_attributes['color']

        query_attributes['shape'] = request.GET.get('shape', '')
        if not query_attributes['shape']: del query_attributes['shape']

        items = Items.objects.filter(**query_attributes)

But I'm pretty sure there's a better way to go about it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

笑饮青盏花 2024-10-06 05:28:54

您可以使用列表比较和“感兴趣的参数”集来完成此操作:

def search_items(request):
    if 'search_name' in request.GET:
        interested_params = ('color', 'shape')
        query_attrs = dict([(param, val) for param, val in request.GET.iteritems() 
                            if param in interested_params and val])

        items = Items.objects.filter(**query_attrs)

只是为了好玩(又名实际上并不这样做),您可以在一行中完成:

def search_items(request):
    items = Items.objects.filter(
        **dict([(param, val) for param, val in request.GET.iteritems() 
                if param in ('color', 'shape') and val])
    ) if 'search_name' in request.GET else None 

You could do it with a list comp and and "interested params" set:

def search_items(request):
    if 'search_name' in request.GET:
        interested_params = ('color', 'shape')
        query_attrs = dict([(param, val) for param, val in request.GET.iteritems() 
                            if param in interested_params and val])

        items = Items.objects.filter(**query_attrs)

Just for fun (aka don't actually do this) you could do it in one line:

def search_items(request):
    items = Items.objects.filter(
        **dict([(param, val) for param, val in request.GET.iteritems() 
                if param in ('color', 'shape') and val])
    ) if 'search_name' in request.GET else None 
云仙小弟 2024-10-06 05:28:54

好吧,你处理这个问题的基本方式似乎是合理的,但你写出来的方式看起来有点有趣。我可能会这样做:

def search_items(request):
    if 'search_name' in request.GET:
        query_attributes = {}

        color = request.GET.get('color', '')
        if color:
            query_attributes['color'] = color

        shape = request.GET.get('shape', '')
        if shape:
            query_attributes['shape'] = shape

        items = Items.objects.filter(**query_attributes)

well, the basic way you are approaching the problem seems sound, but the way you wrote it out looks a little funny. I'd probably do it this way:

def search_items(request):
    if 'search_name' in request.GET:
        query_attributes = {}

        color = request.GET.get('color', '')
        if color:
            query_attributes['color'] = color

        shape = request.GET.get('shape', '')
        if shape:
            query_attributes['shape'] = shape

        items = Items.objects.filter(**query_attributes)
独闯女儿国 2024-10-06 05:28:54

如果您希望它完全动态,您可以使用一点模型自省来找出您实际可以查询的字段,并仅使用这些字段进行过滤。

不过,这个解决方案不允许您在 GET 参数中使用 __lookups,不知道您是否需要它。

def search_items(request):
    if 'search_name' in request.GET:
        all_fields = Items._meta.get_all_field_names()
        filters = [(k, v) for k, v in request.GET.items() if k in all_fields]

        items = Items.objects.filter(*filters)

If you want it to be fully dynamic, you can use a little bit of model introspection to find out what fields you can actually query, and filter only using those.

Though, this solution won't allow you to use __lookups in GET parameters, don't know if you need it.

def search_items(request):
    if 'search_name' in request.GET:
        all_fields = Items._meta.get_all_field_names()
        filters = [(k, v) for k, v in request.GET.items() if k in all_fields]

        items = Items.objects.filter(*filters)
余厌 2024-10-06 05:28:54
def search_items(request):
    try:
        items = Items.objects.filter(**dict([
            (F, request.GET[F]) for F in ('color', 'shape')
        ]))

    except KeyError:
        raise Http404

假设“颜色”和“形状”是必需的 GET 参数。出于安全原因,首选过滤参数的预定义元组。

def search_items(request):
    try:
        items = Items.objects.filter(**dict([
            (F, request.GET[F]) for F in ('color', 'shape')
        ]))

    except KeyError:
        raise Http404

Suppose 'color' and 'shape' are required GET params. Predefined tuple of filtering params is prefered because of security reasons.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文