创建一个复杂的查询?

时间:2014-05-15 11:47:55

标签: python django

创建复杂查询?

请帮助解决问题。

我写了一个过滤器来搜索人物。过滤器包含2个字段:" name"," birth_date"

friends_search.html:

<form class="left filter" action="{% url 'friends_search' %}" method="POST">
    {% csrf_token %}

    <div class="cell">
        <label class="label lbl_name" for="fld_name">Имя</label>

        <input class="fld_name" type="text" name="fld_name" id="fld_name" value="{% if post.fld_name %}{{ post.fld_name }}{% endif %}" />
    </div>          

    <div class="cell">
        <label class="label lbl_birth_date" for="fld_birth_date">Дата рождения</label>

        <input class="fld_birth_date datepicker" type="text" name="fld_birth_date" id="fld_birth_date" value="{% if post.fld_birth_date %}{{ post.fld_birth_date }}{% endif %}" />
    </div>                  

    <div class="cell">
        <input class="submit btn btn-default btn-block" type="submit" name="fld_submit" id="fld_submit" value="Найти" />
    </div>
</form> 

views.py:

@login_required 
def friends_search(request):
    search_result = None
    post = None

    if request.method == 'POST':    
        post = request.POST

        if request.POST.get('fld_name'):
            try:
                fld_name = request.POST.get('fld_name')
                fld_birth_date = request.POST.get('fld_birth_date')

                if q_name:
                    q_name = Q(nickname__icontains=fld_name.strip()))               

                if q_birth_date:
                    q_birth_date = Q(birth_date__icontains=fld_birth_date.strip())

                search_result = UserProfile.objects.filter(q_name).filter(q_birth_date)     #???????????????????????????    
                if not search_result:
                    search_result = 'null'
            except Exception as exc:
                search_result = 'error' 

    t = loader.get_template('friends_search.html')
    c = RequestContext(request, {
        'city_list': UserProfile.get_city_list(),
        'post': post,
    }]) 
    return HttpResponse(t.render(c)) 

models.py:

class UserProfile(User):    
    nickname = models.CharField(
        'Отображаемое имя',
        max_length=30, 
        blank=False,
    )
    birth_date = models.DateField(
        'Дата рождения',
        blank=True,
        null=True,
    )

问题是我无法从两个领域看:

search_result = UserProfile.objects.filter (q_name). filter (q_birth_date) 

但我可以搜索特定字段:

search_result = UserProfile.objects.filter (q_name) 

&安培;

search_result = UserProfile.objects.filter (q_birth_date) 

我需要您同时使用两个字段进行搜索

2 个答案:

答案 0 :(得分:2)

UserProfile.objects.filter(q_name).filter(q_birth_date)

将搜索两个ie。昵称是 AND birth_date的东西。

如果您要搜索其中任何一个字段或两个字段,都可以将视图更新为

            fld_name = request.POST.get('fld_name')
            fld_birth_date = request.POST.get('fld_birth_date')

            qs = UserProfile.objects.filter() #get all

            if fld_name:
                qs = qs.filter(nickname__icontains=fld_name.strip()))               

            if fld_birth_date:
                qs = qs.filter(birth_date__icontains=fld_birth_date.strip())

            search_result = qs     
            if not search_result:
                search_result = 'null'

您可以取消search_result变量,因为qs与此相同。

答案 1 :(得分:1)

从不捕获基类Exception,除非您正确处理它(即记录错误消息等)。为什么?因为except子句隐藏了代码中的实际问题,并使调试成为一个巨大的痛苦。

request.POST对象只包含普通字符串。虽然fld_birth_date可能是日期格式的字符串,但您无法使用字符串对象过滤DateField。您需要一个实际的date对象来过滤。

您需要做的是将字符串转换为日期对象。例如。如果您的日期始终遵循格式dd-mm-YYYY,则可以执行以下操作:

import datetime

date = datetime.datetime.strftime(request.POST.get('fld_birth_date'), '%d-%m-%Y').date()

最重要的是,你使用if q_nameif q_birth_date,而两者都没有定义,都引发了另一个异常。

代码的if request.method == 'POST'部分应该如下所示:

if request.method == 'POST':
    name = request.POST.get('fld_name', None)
    birth_date_string = request.POST.get('fld_birth_date', '')
    try:
        birth_date = datetime.datetime.strftime(birth_date_string, '%d-%m-%Y').date()
    except ValueError:
        birth_date = None

    search_results = UserProfile.objects.all()
    if name:
        search_results = search_results.filter(name__icontains=name.strip())
    if birth_date:
        search_results = search_results.filter(birth_date=birth_date)

如果您想要一个名称或birth_date匹配的结果:

from django.db.models import Q

q = Q()
if name:
    q |= Q(name__icontains=name.strip())
if birth_date:
    q |= Q(birth_date=birth_date)
search_results = UserProfile.objects.filter(q)