[英]dynamic filter choice field in django
I am using django-filter to filter results on a page. 我正在使用django-filter来过滤页面上的结果。 I am able to use static choice filters like this:
我能够使用像这样的静态选择过滤器:
filters.py filter.py
FILTER_CHOICES = (
('', 'All States'),
('AL', 'Alabama'),
('AK', 'Alaska'),
('AZ', 'Arizona'),
#and so forth, I am not going to list all 50 states for this a question on a forum
)
class SightingFilter(django_filters.FilterSet):
state = django_filters.ChoiceFilter(choices=FILTER_CHOICES)
class Meta:
model = Sighting
fields = ['city', 'store', 'brand', 'product', 'flavor', 'fat', 'size']
So that code above works fine, but if I try to make a dynamic list like "plant_number" below: 因此,上面的代码可以正常工作,但是如果我尝试在下面创建一个类似于“ plant_number”的动态列表:
class SightingFilter(django_filters.FilterSet):
state = django_filters.ChoiceFilter(choices=FILTER_CHOICES)
plant_number = django_filters.ChoiceFilter(choices=[(o.plant_number, o.plant_number + " " + o.manufacturer_name) for o in Plant.objects.all()])
class Meta:
model = Sighting
fields = ['city', 'store', 'brand', 'product', 'flavor', 'fat', 'size']
Then I get the error: 然后我得到错误:
invalid literal for int() with base 10: 以10为底的int()的无效文字:
and it highlights this code in my template 它在我的模板中突出显示了此代码
{% for obj in filter %}
<a href="/sighting/{{ obj.slug }}/ ">{{ obj.date|date:"m/d/Y" }} {{ obj.brand }} ${{ obj.price|intcomma }} </a><br />
{% endfor %}
The plant_number is a CharField in the model (plant numbers use the format XX-XXX, where the X's are digits). plant_number是模型中的CharField(工厂编号使用XX-XXX格式,其中X是数字)。
My view looks like this: 我的看法如下:
def dashboard(request):
if "Clear Filters" in request.GET:
return redirect('/')
else:
filter = SightingFilter(request.GET, queryset=Sighting.objects.all())
context = {'filter': filter, 'request': request}
return render_to_response('dashboard.html', context, context_instance=RequestContext(request))
Thanks for your help! 谢谢你的帮助!
EDIT 1/14/15 编辑1/14/15
So I am pretty certain the issue is that plant_number is a foreign key (sorry didn't include the models.py above). 因此,我可以肯定的问题是plant_number是一个外键(抱歉,上面没有包含models.py)。 That is why it is expecting an int and not a string.
这就是为什么它期望一个int而不是一个字符串。 So now I need to figure out how to get the foreign key value of the plant number instead of just the plant number.
因此,现在我需要弄清楚如何获取工厂编号的外键值,而不仅仅是工厂编号。 I tried:
我试过了:
plant_number = django_filters.ChoiceFilter(choices=[[o.plant_number.id, o.plant_number + " " + o.Manufacturer] for o in Plant.objects.all()])
Also tried: 还尝试了:
plant_number = django_filters.ChoiceFilter(choices=[[o.plant_number_id, o.plant_number + " " + o.Manufacturer] for o in Plant.objects.all()])
Neither works. 都不行。 I get 'unicode' object has no attribute 'id' on the first one and 'Plant' object has no attribute 'plant_number_id' on the second.
我得到的“ unicode”对象在第一个对象上没有属性“ id”,而“ Plant”对象在第二个对象上没有属性“ plant_number_id”。
models.py models.py
class Sighting(models.Model):
date = models.DateField(default=today)
brand = models.CharField(max_length=200)
product = models.CharField(max_length=200)
flavor = models.CharField(max_length=200)
fat = models.DecimalField(max_digits=4, decimal_places=2)
size = models.DecimalField(max_digits=10, decimal_places=2)
price = models.DecimalField(max_digits=10, decimal_places=2)
plant_number = models.ForeignKey('Plant', blank=True, null=True )
store = models.CharField(max_length=200)
city = models.CharField(max_length=200)
state = models.CharField(max_length=200, choices=STATE_CHOICES)
photo = ProcessedImageField(upload_to=yogurtupload,
processors=[ResizeToFit(600, 600)], #Resizes so the largest dimension is 600 (width or height, whichever hits 600 first)
format='JPEG',
options={'quality': 72})
slug = models.SlugField(unique=True)
def save(self):
now = timestamp()
forslug = str(now) + " " + str(self.plant_number) + " " + str(self.brand)
self.slug = slugify(forslug)
super(Sighting, self).save()
def __unicode__(self):
return self.slug
class Plant(models.Model):
plant_number = models.CharField(max_length=200)
Manufacturer = models.CharField(max_length=200)
city = models.CharField(max_length=200)
state = models.CharField(max_length=200, choices=STATE_CHOICES)
slug = models.SlugField(unique=True)
def save(self):
self.slug = slugify(self.plant_number)
super(Plant, self).save()
def __unicode__(self):
return self.slug
That's because FILTER_CHOICES
is tuples in a tuple, not tuples in a list. 这是因为
FILTER_CHOICES
是元组中的元组,而不是列表中的元组。 Try this: 尝试这个:
plant_number = django_filters.ChoiceFilter(choices=((o.plant_number.id, o.plant_number.foobar + " " + o.manufacturer_name) for o in Plant.objects.all()))
So I figured this out, I was passing the plant_number instead of the id , which is what django was expecting since my filter is against the Sightings model and plant_number is a foreign key in the the Sightings model. 所以我弄清楚了,我传递的是plant_number而不是id ,这是django期望的,因为我的过滤器针对Sightings模型,而plant_number是Sightings模型中的外键。 The code that worked:
起作用的代码:
plant_number = django_filters.ChoiceFilter(choices=[[o.id, o.plant_number + " " + o.Manufacturer] for o in Plant.objects.all().order_by('IMS_plant')])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.