我遵循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,
})
答案 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 %}