поле выбора динамического фильтра в django

Я использую django-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']   

Таким образом, приведенный выше код работает нормально, но если я попытаюсь создать динамический список, такой как «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']

Затем я получаю сообщение об ошибке:

недопустимый литерал для int() с базой 10:

и он выделяет этот код в моем шаблоне

{% for obj in filter %}
    <a href="/sighting/{{ obj.slug }}/ ">{{ obj.date|date:"m/d/Y" }} {{ obj.brand }} ${{ obj.price|intcomma }} </a><br />
{% endfor %}

Номер_завода — это CharField в модели (номера заводов используют формат XX-XXX, где X — цифры).

Мой взгляд выглядит так:

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))

Спасибо за вашу помощь!

ИЗМЕНИТЬ 14 января 2015 г.

Поэтому я почти уверен, что проблема в том, что plant_number является внешним ключом (извините, что не включил models.py выше). Вот почему он ожидает int, а не строку. Итак, теперь мне нужно выяснить, как получить значение внешнего ключа номера завода, а не просто номер завода. Я старался:

plant_number = django_filters.ChoiceFilter(choices=[[o.plant_number.id, o.plant_number + " " + o.Manufacturer] for o in Plant.objects.all()])

Также пробовал:

plant_number = django_filters.ChoiceFilter(choices=[[o.plant_number_id, o.plant_number + " " + o.Manufacturer] for o in Plant.objects.all()])

Ни то, ни другое не работает. Я получаю, что объект «Unicode» не имеет атрибута «id» на первом, а объект «Plant» не имеет атрибута «plant_number_id» на втором.

модели.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

person VT_Drew    schedule 13.01.2015    source источник


Ответы (2)


Это потому, что FILTER_CHOICES — это кортежи в кортеже, а не кортежи в списке. Попробуй это:

plant_number = django_filters.ChoiceFilter(choices=((o.plant_number.id, o.plant_number.foobar + " " + o.manufacturer_name) for o in Plant.objects.all()))
person dan-klasson    schedule 13.01.2015
comment
Не помогло, теперь страница вообще не загружается. Я получаю сообщение об ошибке: объект.__new__(генератор) небезопасен, используйте генератор.__new__() В соответствии с django docs варианты могут быть кортежами или списками. Я изменил его на списки внутри списка, и я все еще получаю сообщение об ошибке недействительным литералом для int() с основанием 10: [Вставьте любой номер завода, который я выбрал здесь, например, 01-123] Я не понимаю, почему он ищет для базы 10, поскольку номер завода определяется как CharField. - person VT_Drew; 14.01.2015
comment
ОК, до меня только что дошло, в чем проблема. Я получаю init() base 10: ошибка, потому что plant_number является внешним ключом. Я создаю список таких списков: [[o.plant_number, o.plant_number + + o.manufacture_name]], но на самом деле мне нужно значение внешнего ключа, а не номер завода в качестве первого значения. Я пробовал o.plant_number.id безуспешно. Мне просто нужно выяснить, как получить значение внешнего ключа. Если кто знает поделитесь пожалуйста! - person VT_Drew; 14.01.2015
comment
Отредактировал мой ответ. Помогло бы, если бы вы разместили модель завода - person dan-klasson; 14.01.2015
comment
Дэн Я добавил свои models.py. Я получал ошибку атрибута с вашими двойными подчеркиваниями: AttributeError at / 'Plant' объект не имеет атрибута 'plant_number__id' - person VT_Drew; 14.01.2015
comment
Упс. Должна быть точка, а не двойное подчеркивание. Еще раз отредактировал. - person dan-klasson; 15.01.2015

Итак, я понял это, я передал plant_number вместо id, чего и ожидал django, поскольку мой фильтр не соответствует модели Sightings и plant_number< /strong> — это внешний ключ в модели Sightings. Код, который работал:

plant_number = django_filters.ChoiceFilter(choices=[[o.id, o.plant_number + " " + o.Manufacturer] for o in Plant.objects.all().order_by('IMS_plant')])
person VT_Drew    schedule 15.01.2015