django-filters:如何使用 ModelChoiceFilter,无法将 类 添加到表单字段并且无法设置表单标签
django-filters: How do I use ModelChoiceFilter, unable to add classes to form fields and unable to set form labels
我正在尝试创建一个下拉表单作为过滤器,但它不起作用,我正在尝试将其与文本字段一起使用。字段从中提取的两个模型字段分别是 TextField 和 CharField。
filters.py
import django_filters as df
from django import forms
from django.utils.translation import ugettext_lazy as _
from .models import FoodTruck
class FoodTruckFilter(df.FilterSet):
category_queryset = FoodTruck.objects.exclude(category='').values_list('category', flat=True).distinct().order_by('category')
category_drop_down = df.ModelChoiceFilter(queryset=category_queryset)
class Meta:
model = FoodTruck
fields = {
'name': ['icontains'],
'category': ['icontains'],
}
labels = {
'name': _('Food Truck Name'),
'category': _('Category'),
}
#widget = {
# 'name': forms.TextInput(attrs={'class': 'form-control'}),
# 'category': forms.Select(attrs={'class': 'form-control'})
#}
models.py
class FoodTruck(models.Model):
name = models.CharField(max_length=25)
category = models.CharField(max_length=20)
bio = models.TextField()
avatar_url = models.URLField(blank=True)
avatar_alt_text = models.CharField(max_length=20, blank=True)
avatar_title = models.CharField(max_length=20, blank=True)
cover_photo_url = models.URLField(blank=True)
cover_photo_alt_text = models.CharField(max_length=20, default="No photo provided")
cover_photo_title = models.CharField(max_length=20, default="No photo provided")
website = models.URLField(blank=True, null=True)
facebook = models.URLField(max_length=100, blank=True, null=True)
instagram = models.CharField(max_length=30, blank=True, null=True)
twitter = models.CharField(max_length=50, blank=True, null=True)
def __str__(self):
return self.name
views.py
class TruckListView(generic.ListView):
model = FoodTruck
template_name = 'truckReviews/landing.html'
ordering = 'name'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['filter'] = FoodTruckFilter(self.request.GET, queryset=self.get_queryset())
return context
landing.html
{% extends "truckReviews/base.html" %}
{% block content %}
<!--Filter Nav-->
<nav class="d-flex justify-content-center align-items-center sticky-top mt-2">
<form method="get" class="border rounded p-2 bg-light">
{% for field in filter.form %}
<span class="form-group">
<label for="{{ field.id_for_label }}" class="control-label">
{{ field.label }}:
</label>
{{ field }}
</span>
{% endfor %}
<button type="submit" class="btn btn-success">Search</button>
</form>
</nav>
<!--Food Truck Cards-->
<div class="d-flex flex-row flex-wrap justify-content-around">
{% for truck in filter.qs %}
<div class="card mb-2 mt-2" style="width: 20rem;">
<img src="{{ truck.cover_photo_url }}" alt="{{ truck.cover_photo_alt_text }}" class="card-img-top">
<div class="card-body">
<h5 class="card-title"> {{ truck.name }}</h5>
<h6 class="card-text text-muted">{{ truck.category }}</h6>
<p class="card-text" style="font-size: 0.8rem;"> {{ truck.bio }}</p>
<a href="{% url 'truck-review' truck.truck %}" class="btn btn-outline-info">View Truck</a>
</div>
</div>
{% endfor %}
</div>
{% endblock content %}
这里有一些图片试图解释发生了什么:
过滤导航:https://i.stack.imgur.com/W2VAY.png
当我尝试使用 'category_drop_down' 进行搜索时,它仍然显示所有类别的所有食品卡车。
https://i.stack.imgur.com/y9Kxn.png
但是当我使用文本字段时,它会正确过滤卡车。
https://i.stack.imgur.com/5pz4o.png
我怎样才能使过滤器使用下拉菜单而不是文本字段?
另外,如何更改表单字段的标签,并向它们添加 类 。我尝试使用下面的代码,但没有用。
labels = {
'name': _('Food Truck Name'),
'category': _('Category'),
}
widget = {
'name': forms.TextInput(attrs={'class': 'form-control'}),
'category': forms.Select(attrs={'class': 'form-control'})
}
提前感谢您的帮助。
要更改标签,请在您的 FoodTruckFilter 中添加以下内容:
def __init__(self, *args, **kwargs):
super(FoodTruckFilter, self).__init__(*args, **kwargs)
self.filters['name__icontains'].label = 'Food Truck Name'
self.filters['category__icontains'].label = 'Category'
我正在尝试创建一个下拉表单作为过滤器,但它不起作用,我正在尝试将其与文本字段一起使用。字段从中提取的两个模型字段分别是 TextField 和 CharField。
filters.py
import django_filters as df
from django import forms
from django.utils.translation import ugettext_lazy as _
from .models import FoodTruck
class FoodTruckFilter(df.FilterSet):
category_queryset = FoodTruck.objects.exclude(category='').values_list('category', flat=True).distinct().order_by('category')
category_drop_down = df.ModelChoiceFilter(queryset=category_queryset)
class Meta:
model = FoodTruck
fields = {
'name': ['icontains'],
'category': ['icontains'],
}
labels = {
'name': _('Food Truck Name'),
'category': _('Category'),
}
#widget = {
# 'name': forms.TextInput(attrs={'class': 'form-control'}),
# 'category': forms.Select(attrs={'class': 'form-control'})
#}
models.py
class FoodTruck(models.Model):
name = models.CharField(max_length=25)
category = models.CharField(max_length=20)
bio = models.TextField()
avatar_url = models.URLField(blank=True)
avatar_alt_text = models.CharField(max_length=20, blank=True)
avatar_title = models.CharField(max_length=20, blank=True)
cover_photo_url = models.URLField(blank=True)
cover_photo_alt_text = models.CharField(max_length=20, default="No photo provided")
cover_photo_title = models.CharField(max_length=20, default="No photo provided")
website = models.URLField(blank=True, null=True)
facebook = models.URLField(max_length=100, blank=True, null=True)
instagram = models.CharField(max_length=30, blank=True, null=True)
twitter = models.CharField(max_length=50, blank=True, null=True)
def __str__(self):
return self.name
views.py
class TruckListView(generic.ListView):
model = FoodTruck
template_name = 'truckReviews/landing.html'
ordering = 'name'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['filter'] = FoodTruckFilter(self.request.GET, queryset=self.get_queryset())
return context
landing.html
{% extends "truckReviews/base.html" %}
{% block content %}
<!--Filter Nav-->
<nav class="d-flex justify-content-center align-items-center sticky-top mt-2">
<form method="get" class="border rounded p-2 bg-light">
{% for field in filter.form %}
<span class="form-group">
<label for="{{ field.id_for_label }}" class="control-label">
{{ field.label }}:
</label>
{{ field }}
</span>
{% endfor %}
<button type="submit" class="btn btn-success">Search</button>
</form>
</nav>
<!--Food Truck Cards-->
<div class="d-flex flex-row flex-wrap justify-content-around">
{% for truck in filter.qs %}
<div class="card mb-2 mt-2" style="width: 20rem;">
<img src="{{ truck.cover_photo_url }}" alt="{{ truck.cover_photo_alt_text }}" class="card-img-top">
<div class="card-body">
<h5 class="card-title"> {{ truck.name }}</h5>
<h6 class="card-text text-muted">{{ truck.category }}</h6>
<p class="card-text" style="font-size: 0.8rem;"> {{ truck.bio }}</p>
<a href="{% url 'truck-review' truck.truck %}" class="btn btn-outline-info">View Truck</a>
</div>
</div>
{% endfor %}
</div>
{% endblock content %}
这里有一些图片试图解释发生了什么:
过滤导航:https://i.stack.imgur.com/W2VAY.png
当我尝试使用 'category_drop_down' 进行搜索时,它仍然显示所有类别的所有食品卡车。
https://i.stack.imgur.com/y9Kxn.png
但是当我使用文本字段时,它会正确过滤卡车。
https://i.stack.imgur.com/5pz4o.png
我怎样才能使过滤器使用下拉菜单而不是文本字段?
另外,如何更改表单字段的标签,并向它们添加 类 。我尝试使用下面的代码,但没有用。
labels = {
'name': _('Food Truck Name'),
'category': _('Category'),
}
widget = {
'name': forms.TextInput(attrs={'class': 'form-control'}),
'category': forms.Select(attrs={'class': 'form-control'})
}
提前感谢您的帮助。
要更改标签,请在您的 FoodTruckFilter 中添加以下内容:
def __init__(self, *args, **kwargs):
super(FoodTruckFilter, self).__init__(*args, **kwargs)
self.filters['name__icontains'].label = 'Food Truck Name'
self.filters['category__icontains'].label = 'Category'