自定义标签,例如使用 django-filter

Bul*_*lva 4 django django-models django-forms django-filter modelchoicefield

我有观察者模型,它通过 OneToOneRelation 扩展用户模型。我对具有观察者外键的模型清单进行了过滤。这是 models.py 代码:

\n\n
class Observer(models.Model):\n    user = models.OneToOneField(User, on_delete=models.CASCADE)\n    rating = models.IntegerField(default=0)\n    bird_ratings = models.ManyToManyField(\'BirdName\', through=\'BirdRatings\')\n\nclass Checklist(gismodels.Model):\n    date = models.DateField()\n    time_start = models.TimeField(null=True)\n    time_end = models.TimeField(null=True)\n    site_name = models.CharField(max_length=200)\n    municipality = models.CharField(max_length=200)\n    observer = models.ForeignKey(Observer, null=True, default=\'\')\n    other_observers = models.CharField(max_length=150, default=\'\')\n    note = models.CharField(max_length=2000)\n    location_note = models.CharField(max_length=2000, default=\'\')\n    position = gismodels.PointField(null=True, srid=4326)\n    created = models.DateTimeField(db_index=True, null=True)\n    rating = models.IntegerField(default=0)\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后我在filters.py中创建了ChecklistFilter类:

\n\n
class ChecklistFilter(django_filters.FilterSet):\n    date = DateFromToRangeFilter(label=\'Datum pozorov\xc3\xa1n\xc3\xad\', widget=RangeWidget(attrs={\'display\': \'inline\'}))\n    #groups = django_filters.ModelMultipleChoiceFilter(queryset=User.objects.filter(), widget=forms.CheckboxSelectMultiple)\n    created = DateFilter(label=\'Datum vlo\xc5\xbeen\xc3\xad\')\n    observer = ModelChoiceFilter(queryset=Observer.objects.filter(), label=\'Pozorovatel\')\n    municipality = CharFilter(label=\'Obec\')\n    oblast = CharFilter(label=\'Oblast\')\n    rating = NumberFilter(label=\'Hodnocen\xc3\xad\')\n\n    class Meta:\n        model = Checklist\n        fields = [\'date\', \'created\', \'observer\', \'municipality\', \'site_name\', \'rating\']\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我的模板代码的一部分,我在其中使用观察者字段:

\n\n
<div class="col-sm-2">\n    {{ filter.form.observer.label_tag }}\n    {% render_field filter.form.observer class="form-control" %}\n</div>\n
Run Code Online (Sandbox Code Playgroud)\n\n

但问题是我不需要获取观察者对象,但我需要链接到观察者模型的用户模型中的last_name。在表单中,我只是扩展 ModelChoiceField 并覆盖 label_from_instance() 方法。\n但这在这里不起作用。Django-filter 使用此类,但覆盖在这里不起作用。我试过这个:

\n\n
from .models import Checklist, Observer\nfrom django.contrib.auth.models import User\nimport django_filters\nfrom django_filters import DateFromToRangeFilter, DateFilter, CharFilter, NumberFilter, ModelChoiceFilter\nfrom django_filters.widgets import RangeWidget\nfrom django import forms\n\n\nclass ChecklistModelChoiceField(forms.ModelChoiceField):\n    def label_from_instance(self, obj):\n        return obj.user.last_name\n\nclass ChecklistFilter(django_filters.FilterSet):\n    date = DateFromToRangeFilter(label=\'Datum pozorov\xc3\xa1n\xc3\xad\', widget=RangeWidget(attrs={\'display\': \'inline\'}))\n    #groups = django_filters.ModelMultipleChoiceFilter(queryset=User.objects.filter(), widget=forms.CheckboxSelectMultiple)\n    created = DateFilter(label=\'Datum vlo\xc5\xbeen\xc3\xad\')\n    observer = ChecklistModelChoiceField(queryset=Observer.objects.filter(), label=\'Pozorovatel\')\n    municipality = CharFilter(label=\'Obec\')\n    oblast = CharFilter(label=\'Oblast\')\n    rating = NumberFilter(label=\'Hodnocen\xc3\xad\')\n\n    class Meta:\n        model = Checklist\n        fields = [\'date\', \'created\', \'observer\', \'municipality\', \'site_name\', \'rating\']\n
Run Code Online (Sandbox Code Playgroud)\n\n

网站上的选择字段有观察者对象:\n在此输入图像描述

\n\n

编辑
\n是的,我都尝试过。然后我尝试:

\n\n
class ChecklistModelChoiceField(django_filters.ModelChoiceFilter):\n    def label_from_instance(self, obj):\n        return obj.user.last_name\n
Run Code Online (Sandbox Code Playgroud)\n\n

没有错误,但是label_from_instance()没有使用。仍然是 select 中的 Observer 对象。

\n\n

我犯了一个错误。ModelChoiceFilter 不扩展 ChoiceField。过滤器中的代码如下所示。它只是财产:

\n\n
class ModelChoiceFilter(QuerySetRequestMixin, Filter):\n    field_class = forms.ModelChoiceField\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以我的第一个想法行不通。还有其他机会如何制作我需要的东西吗?

\n

DHe*_*rls 10

我知道这个问题已经存在一年多了,但我遇到了同样的问题并使用 ModelChoiceFilter 找到了解决方案。所以如果其他人遇到这个:

\n\n
from .models import Checklist, Observer\nfrom django.contrib.auth.models import User\nimport django_filters\nfrom django_filters import DateFromToRangeFilter, DateFilter, CharFilter, NumberFilter, ModelChoiceFilter\nfrom django_filters.widgets import RangeWidget\nfrom django import forms\n\nclass ChecklistFilter(django_filters.FilterSet):\n    date = DateFromToRangeFilter(label='Datum pozorov\xc3\xa1n\xc3\xad', widget=RangeWidget(attrs={'display': 'inline'}))\n    #groups = django_filters.ModelMultipleChoiceFilter(queryset=User.objects.filter(), widget=forms.CheckboxSelectMultiple)\n    created = DateFilter(label='Datum vlo\xc5\xbeen\xc3\xad')\n    observer = ModelChoiceFilter(queryset=Observer.objects.filter(), label='Pozorovatel')\n    municipality = CharFilter(label='Obec')\n    oblast = CharFilter(label='Oblast')\n    rating = NumberFilter(label='Hodnocen\xc3\xad')\n\n    class Meta:\n        model = Checklist\n        fields = ['date', 'created', 'observer', 'municipality', 'site_name', 'rating']\n\n    def __init__(self, *args, **kwargs):\n        super(ChecklistFilter, self).__init__(*args, **kwargs)\n        # You need to override the label_from_instance method in the filter's form field\n        self.filters['thon_group'].field.label_from_instance = lambda obj: obj.user.last_name\n
Run Code Online (Sandbox Code Playgroud)\n