多种搜索标准django形式

时间:2014-08-19 19:19:08

标签: python django django-forms django-views

我遵循Django文档以构建多个搜索条件表单。我的第一个问题是,这是否应该是在查询中过滤值的正确方法,以及如何添加外键和m2m在搜索条件中显示为选择和多选。这是我的代码到目前为止。感谢

表单

class SearchPropertyForm(forms.Form):
    name = forms.CharField(max_length = 100, widget = forms.TextInput(attrs = {'class':'form-control', 'placeholder':'Nombre'}))
    activity = forms.ModelChoiceField(queryset = Activity.objects.all(), widget = forms.Select(attrs = {'class':'form-control', 'placeholder':'Actividad'}))
    currency = forms.ModelChoiceField(queryset = Currency.objects.all(), widget = forms.Select(attrs = {'class':'form-control', 'placeholder':'Moneda'}))
    price_from = forms.IntegerField(widget = forms.TextInput(attrs = {'class':'form-control', 'placeholder':'Precio-Desde'}))
    price_to = forms.IntegerField(widget = forms.TextInput(attrs = {'class':'form-control', 'placeholder':'Precio-Hasta'}))
    categories = forms.ModelMultipleChoiceField(queryset = Category.objects.all(), widget = forms.SelectMultiple(attrs = {'class':'form-control', 'placeholder':'Categorias'}))

模型

class Property(models.Model):
    class Meta:
        verbose_name_plural = "properties"

    name = models.CharField(max_length = 200)
    description = models.TextField(max_length = 500)
    address = models.CharField(max_length = 200)
    sqft = models.DecimalField(max_digits = 6, decimal_places = 2)
    beds = models.IntegerField()
    baths = models.IntegerField()
    status = models.BooleanField(default = True)
    price = models.DecimalField(max_digits = 6, decimal_places = 2)
    likes = models.IntegerField()
    categories = models.ManyToManyField(Category, null = True, blank = True)
    currency_type = models.ForeignKey(Currency)
    activity_type = models.ForeignKey(Activity)
    creation_date = models.DateTimeField(auto_now_add = True)
    edition_date = models.DateTimeField(default = timezone.now)

    def __unicode__(self):
        return self.name

查看

def search_properties(request):
    if request.method == 'POST':
        form = SearchPropertyForm(request.POST)
        if form.is_valid():
            name = form.cleaned_data['name']
            activity = form.cleaned_data['activity']
            currency = form.cleaned_data['currency']
            price_from = form.cleaned_data['price_from']
            price_to = form.cleaned_data['price_to']
            categories = form.cleaned_data['categories']

            properties = Property.objects.filter(name__icontains = name).filter(
            activity_type__exact = int(activity)).filter(
            currency_type__exact = int(currency)).filter(
            price_from__gte = int(price_from)).filter(
            price_from__lte = int(price_to)).filter(
            categories__exact = int(categories))

            return render(request, 'properties/search_properties.html', {
                'properties': properties,
                'media_url': settings.MEDIA_URL,
                'form':form,
            })

    else:
        form = SearchPropertyForm()

    properties = Property.objects.filter(status = True)

    return render(request, 'properties/search_properties.html', {
        'properties': properties,
        'media_url': settings.MEDIA_URL,
        'form':form,
    })

2 个答案:

答案 0 :(得分:0)

如果您尝试进行Q查询,可以使用or对象。

https://docs.djangoproject.com/en/dev/topics/db/queries/#complex-lookups-with-q-objects

所以你的代码可能是这样的。

from django.db.models import Q
properties = Property.objects.filter(Q(name__icontains = name)|
                Q(activity_type__exact = int(activity))|
                Q(currency_type__exact = int(currency))|
                Q(price_from__gte = int(price_from))|
                Q(price_from__lte = int(price_to))|
                Q(categories__exact = int(categories))

Q对象|(管道)代表or个查询,&代表and个查询。

因此,如果任何查询匹配,这将返回。

对于表单部分,我使用如下所示的Modelform,它自动获取外键和多选。

class SearchPropertyForm(forms.ModelForm):

    class Meta:
        model = Property
        fields = ('name', 'activity','currency', 'price_form')

答案 1 :(得分:0)

您可以使用Q个对象,或只使用django-filter

  

Django-filter提供了一种根据用户提供的参数过滤查询集的简单方法。

安装完成后,创建一个forms.py(因为过滤器是一种表单),在其中添加以下内容:

import django_filters

from .models import Property

class PropertyFilter(django_filters.FilterSet):
    class Meta:
        model = Property

然后,您必须从views.py

连接它
from .forms import PropertyFilter

def search(request):
   f = PropertyFilter(request.GET, Property.objects.all())
   return render(request, 'search.html', {'filter': f})

您的模板search.html

<form method="GET" role="form">
   {{ f.form }}
   <input type="submit" />
</form>
{% if f|length %}
   {% for obj in f %}
       {{ obj }}
   {% endfor %}
{% else %}
   Sorry, no results for your search criteria
{% endif %}