0

OneToOneRelationでユーザーモデルを拡張するObserverモデルがあります。私はオブザーバーに外部キーを持っているモデルチェックリストにフィルターをかけました。これはmodels.pyコードです:django-filterでのカスタムラベル

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

しかし、問題は私がオブザーバーモデルにリンクされているUserモデルからLAST_NAME必要オブザーバオブジェクトを取得する必要がありますが、dont'tということです。フォームでは、単にModelChoiceFieldを拡張し、label_from_instance()メソッドをオーバーライドします。 これはここでは機能しません。 Django-filterはこのクラスを使用しますが、ここでは動作しません。私はこれを試してみました:

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'] 

選択フィールドを、その後、ウェブサイト上のオブザーバオブジェクトがあります。 enter image description here

EDIT
はい、私はそれらの両方を試してみましたが。そして、私が試した:

class ChecklistModelChoiceField(django_filters.ModelChoiceFilter): 
    def label_from_instance(self, obj): 
     return obj.user.last_name 

エラーはありませんが、label_from_instance()が使用されていません。選択中のObserverオブジェクトをスローします。

私は間違いをしました。 ModelChoiceFilterはChoiceFieldを拡張しません。フィルタのコードは次のようになります。それはちょうどプロパティです:

class ModelChoiceFilter(QuerySetRequestMixin, Filter): 
    field_class = forms.ModelChoiceField 

私の最初のアイデアは動作しません。私に必要なものを作る方法は他にもありますか?

+0

コードの仕組みがわかりません。 1つの問題は、 'ChecklistFilter.observer'がフィルタではなくフォームフィールドであることです。 – Sherpa

+0

私は間違いました。 ModelChoiceFilterはModelChoiceFieldを拡張しません。それはただの財産です。だから私はこのクラスには存在しないメソッドをオーバーライドし、そのメソッドは決して使用されませんでした。 – Bulva

答えて

0

解決策が見つかりました。 ModelChoiceFilter以外のChoiceFilterを使用して、選択肢として、observerの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') 
関連する問題