使用 django-filter 的自定义标签
Custom label for instance with django-filter
我有一个 Observer 模型,它通过 OneToOneRelation 扩展了 User 模型。我对具有观察者外键的模型清单进行了过滤。这是 models.py 代码:
class Observer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
rating = models.IntegerField(default=0)
bird_ratings = models.ManyToManyField('BirdName', through='BirdRatings')
class Checklist(gismodels.Model):
date = models.DateField()
time_start = models.TimeField(null=True)
time_end = models.TimeField(null=True)
site_name = models.CharField(max_length=200)
municipality = models.CharField(max_length=200)
observer = models.ForeignKey(Observer, null=True, default='')
other_observers = models.CharField(max_length=150, default='')
note = models.CharField(max_length=2000)
location_note = models.CharField(max_length=2000, default='')
position = gismodels.PointField(null=True, srid=4326)
created = models.DateTimeField(db_index=True, null=True)
rating = models.IntegerField(default=0)
然后我在 filters.py 中制作了 ChecklistFilter class:
class ChecklistFilter(django_filters.FilterSet):
date = DateFromToRangeFilter(label='Datum pozorování', widget=RangeWidget(attrs={'display': 'inline'}))
#groups = django_filters.ModelMultipleChoiceFilter(queryset=User.objects.filter(), widget=forms.CheckboxSelectMultiple)
created = DateFilter(label='Datum vložení')
observer = ModelChoiceFilter(queryset=Observer.objects.filter(), label='Pozorovatel')
municipality = CharFilter(label='Obec')
oblast = CharFilter(label='Oblast')
rating = NumberFilter(label='Hodnocení')
class Meta:
model = Checklist
fields = ['date', 'created', 'observer', 'municipality', 'site_name', 'rating']
这是我在模板中使用观察者字段的代码的一部分:
<div class="col-sm-2">
{{ filter.form.observer.label_tag }}
{% render_field filter.form.observer class="form-control" %}
</div>
但问题是我不需要获取观察者对象,但我需要来自链接到观察者模型的用户模型的last_name。在表单中,我只是扩展了 ModelChoiceField 并覆盖了 label_from_instance() 方法。
但这在这里不起作用。 Django-filter 使用这个 classes 但overiding在这里不起作用。我试过这个:
from .models import Checklist, Observer
from django.contrib.auth.models import User
import django_filters
from django_filters import DateFromToRangeFilter, DateFilter, CharFilter, NumberFilter, ModelChoiceFilter
from django_filters.widgets import RangeWidget
from django import forms
class ChecklistModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.user.last_name
class ChecklistFilter(django_filters.FilterSet):
date = DateFromToRangeFilter(label='Datum pozorování', widget=RangeWidget(attrs={'display': 'inline'}))
#groups = django_filters.ModelMultipleChoiceFilter(queryset=User.objects.filter(), widget=forms.CheckboxSelectMultiple)
created = DateFilter(label='Datum vložení')
observer = ChecklistModelChoiceField(queryset=Observer.objects.filter(), label='Pozorovatel')
municipality = CharFilter(label='Obec')
oblast = CharFilter(label='Oblast')
rating = NumberFilter(label='Hodnocení')
class Meta:
model = Checklist
fields = ['date', 'created', 'observer', 'municipality', 'site_name', 'rating']
然后网站上的选择字段有观察者对象:
编辑
是的,我都试过了。然后我试了:
class ChecklistModelChoiceField(django_filters.ModelChoiceFilter):
def label_from_instance(self, obj):
return obj.user.last_name
没有错误,但是没有使用label_from_instance()
。 select.
中仍然是 Observer 对象
我错了。 ModelChoiceFilter 不扩展 ChoiceField。过滤器中的代码如下所示。就是 属性:
class ModelChoiceFilter(QuerySetRequestMixin, Filter):
field_class = forms.ModelChoiceField
所以我的第一个想法行不通。还有其他机会如何制作我需要的东西吗?
我找到了解决方案。我使用 ChoiceFilter 而不是 ModelChoiceFilter,然后为选择调用一个方法,在该方法中我创建具有观察者 ID 和用户模型名称的元组的元组。
def get_last_names():
last_names = ()
observers = Observer.objects.all()
for obs in observers:
last_names += (obs.id, obs.user.last_name),
return last_names
observer = ChoiceFilter(choices=get_last_names, label='Observer')
我知道这个问题已有一年多了,但我 运行 遇到了同样的问题并找到了使用 ModelChoiceFilter 的解决方案。因此,如果其他人 运行 参与其中:
from .models import Checklist, Observer
from django.contrib.auth.models import User
import django_filters
from django_filters import DateFromToRangeFilter, DateFilter, CharFilter, NumberFilter, ModelChoiceFilter
from django_filters.widgets import RangeWidget
from django import forms
class ChecklistFilter(django_filters.FilterSet):
date = DateFromToRangeFilter(label='Datum pozorování', widget=RangeWidget(attrs={'display': 'inline'}))
#groups = django_filters.ModelMultipleChoiceFilter(queryset=User.objects.filter(), widget=forms.CheckboxSelectMultiple)
created = DateFilter(label='Datum vložení')
observer = ModelChoiceFilter(queryset=Observer.objects.filter(), label='Pozorovatel')
municipality = CharFilter(label='Obec')
oblast = CharFilter(label='Oblast')
rating = NumberFilter(label='Hodnocení')
class Meta:
model = Checklist
fields = ['date', 'created', 'observer', 'municipality', 'site_name', 'rating']
def __init__(self, *args, **kwargs):
super(ChecklistFilter, self).__init__(*args, **kwargs)
# You need to override the label_from_instance method in the filter's form field
self.filters['thon_group'].field.label_from_instance = lambda obj: obj.user.last_name
我有一个 Observer 模型,它通过 OneToOneRelation 扩展了 User 模型。我对具有观察者外键的模型清单进行了过滤。这是 models.py 代码:
class Observer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
rating = models.IntegerField(default=0)
bird_ratings = models.ManyToManyField('BirdName', through='BirdRatings')
class Checklist(gismodels.Model):
date = models.DateField()
time_start = models.TimeField(null=True)
time_end = models.TimeField(null=True)
site_name = models.CharField(max_length=200)
municipality = models.CharField(max_length=200)
observer = models.ForeignKey(Observer, null=True, default='')
other_observers = models.CharField(max_length=150, default='')
note = models.CharField(max_length=2000)
location_note = models.CharField(max_length=2000, default='')
position = gismodels.PointField(null=True, srid=4326)
created = models.DateTimeField(db_index=True, null=True)
rating = models.IntegerField(default=0)
然后我在 filters.py 中制作了 ChecklistFilter class:
class ChecklistFilter(django_filters.FilterSet):
date = DateFromToRangeFilter(label='Datum pozorování', widget=RangeWidget(attrs={'display': 'inline'}))
#groups = django_filters.ModelMultipleChoiceFilter(queryset=User.objects.filter(), widget=forms.CheckboxSelectMultiple)
created = DateFilter(label='Datum vložení')
observer = ModelChoiceFilter(queryset=Observer.objects.filter(), label='Pozorovatel')
municipality = CharFilter(label='Obec')
oblast = CharFilter(label='Oblast')
rating = NumberFilter(label='Hodnocení')
class Meta:
model = Checklist
fields = ['date', 'created', 'observer', 'municipality', 'site_name', 'rating']
这是我在模板中使用观察者字段的代码的一部分:
<div class="col-sm-2">
{{ filter.form.observer.label_tag }}
{% render_field filter.form.observer class="form-control" %}
</div>
但问题是我不需要获取观察者对象,但我需要来自链接到观察者模型的用户模型的last_name。在表单中,我只是扩展了 ModelChoiceField 并覆盖了 label_from_instance() 方法。 但这在这里不起作用。 Django-filter 使用这个 classes 但overiding在这里不起作用。我试过这个:
from .models import Checklist, Observer
from django.contrib.auth.models import User
import django_filters
from django_filters import DateFromToRangeFilter, DateFilter, CharFilter, NumberFilter, ModelChoiceFilter
from django_filters.widgets import RangeWidget
from django import forms
class ChecklistModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.user.last_name
class ChecklistFilter(django_filters.FilterSet):
date = DateFromToRangeFilter(label='Datum pozorování', widget=RangeWidget(attrs={'display': 'inline'}))
#groups = django_filters.ModelMultipleChoiceFilter(queryset=User.objects.filter(), widget=forms.CheckboxSelectMultiple)
created = DateFilter(label='Datum vložení')
observer = ChecklistModelChoiceField(queryset=Observer.objects.filter(), label='Pozorovatel')
municipality = CharFilter(label='Obec')
oblast = CharFilter(label='Oblast')
rating = NumberFilter(label='Hodnocení')
class Meta:
model = Checklist
fields = ['date', 'created', 'observer', 'municipality', 'site_name', 'rating']
然后网站上的选择字段有观察者对象:
编辑
是的,我都试过了。然后我试了:
class ChecklistModelChoiceField(django_filters.ModelChoiceFilter):
def label_from_instance(self, obj):
return obj.user.last_name
没有错误,但是没有使用label_from_instance()
。 select.
我错了。 ModelChoiceFilter 不扩展 ChoiceField。过滤器中的代码如下所示。就是 属性:
class ModelChoiceFilter(QuerySetRequestMixin, Filter):
field_class = forms.ModelChoiceField
所以我的第一个想法行不通。还有其他机会如何制作我需要的东西吗?
我找到了解决方案。我使用 ChoiceFilter 而不是 ModelChoiceFilter,然后为选择调用一个方法,在该方法中我创建具有观察者 ID 和用户模型名称的元组的元组。
def get_last_names():
last_names = ()
observers = Observer.objects.all()
for obs in observers:
last_names += (obs.id, obs.user.last_name),
return last_names
observer = ChoiceFilter(choices=get_last_names, label='Observer')
我知道这个问题已有一年多了,但我 运行 遇到了同样的问题并找到了使用 ModelChoiceFilter 的解决方案。因此,如果其他人 运行 参与其中:
from .models import Checklist, Observer
from django.contrib.auth.models import User
import django_filters
from django_filters import DateFromToRangeFilter, DateFilter, CharFilter, NumberFilter, ModelChoiceFilter
from django_filters.widgets import RangeWidget
from django import forms
class ChecklistFilter(django_filters.FilterSet):
date = DateFromToRangeFilter(label='Datum pozorování', widget=RangeWidget(attrs={'display': 'inline'}))
#groups = django_filters.ModelMultipleChoiceFilter(queryset=User.objects.filter(), widget=forms.CheckboxSelectMultiple)
created = DateFilter(label='Datum vložení')
observer = ModelChoiceFilter(queryset=Observer.objects.filter(), label='Pozorovatel')
municipality = CharFilter(label='Obec')
oblast = CharFilter(label='Oblast')
rating = NumberFilter(label='Hodnocení')
class Meta:
model = Checklist
fields = ['date', 'created', 'observer', 'municipality', 'site_name', 'rating']
def __init__(self, *args, **kwargs):
super(ChecklistFilter, self).__init__(*args, **kwargs)
# You need to override the label_from_instance method in the filter's form field
self.filters['thon_group'].field.label_from_instance = lambda obj: obj.user.last_name