So übergeben Sie den aktuellen Benutzer an Django_filters ModelChoiceFilter Queryset.

Ich versuche, das ModelChoiceFilter basierend auf dem aktuellen Benutzer zu filtern. Ich habe die init -Methode im Filter verwendet, aber es ist fehlgeschlagen:

Hier ist der Code, den ich verwendet habe:

views.py

def requests_reports(request):
    f = RequestsFilter(request.GET, queryset=LeaveRequest.objects.filter(user=request.user), user=request.user)
    context = {
        'filter': f,
    }
    return render(request, 'requests_reports.html', context)

forms.py

class RequestsFilter(django_filters.FilterSet):
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')
        super(RequestsFilter, self).__init__(*args, **kwargs)
        self.fields['employee'].queryset = Employee.objects.filter(user=self.user)

    start_date = DateFilter(field_name='date_time', lookup_expr='gt', widget=forms.TextInput(attrs={'type': 'date'}))
    end_date = DateFilter(field_name='date_time', lookup_expr='lt', widget=forms.TextInput(attrs={'type': 'date'}))

    class Meta:
        model = LeaveRequest
        fields = ['employee', 'type']

Es gibt diesen Fehler zurück:

'RequestsFilter' object has no attribute 'fields'
2
amgad wagdy 19 Feb. 2020 im 17:37

3 Antworten

Beste Antwort

Verwenden Sie das normale _init_, aber anstelle von self.fields['field_name] self.filters[field_name]

Versuchen Sie diesen Code:

class RequestsFilter(django_filters.FilterSet):
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')
        super().__init__(*args, **kwargs)
        self.filters['employee'].queryset = Employee.objects.filter(user=self.user)
    start_date = DateFilter(field_name='date_time', lookup_expr='gt', widget=forms.TextInput(attrs={'type': 'date'}))
    end_date = DateFilter(field_name='date_time', lookup_expr='lt', widget=forms.TextInput(attrs={'type': 'date'}))
    employee = django_filters.ModelChoiceFilter(queryset=None, field_name='employee' )
    class Meta:
        model = LeaveRequest
        fields = ['employee', 'type', 'date_time']
0
Ahmed Wagdi 24 Feb. 2020 im 16:47

Sie können eine benutzerdefinierte Methode festlegen. Weitere Informationen hier: https: //django-filter.readthedocs.io/de/master/guide/usage.html#customize-filtering-with-filter-method

class RequestsFilter(django_filters.FilterSet):
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')
        super().__init__(*args, **kwargs)

    employee = django_filters.filters.ModelMultipleChoiceFilter(
        field_name='employee',
        queryset=Employee.objects.all(),
        method="filter_employee",
    )
    start_date = DateFilter(field_name='date_time', lookup_expr='gt', widget=forms.TextInput(attrs={'type': 'date'}))
    end_date = DateFilter(field_name='date_time', lookup_expr='lt', widget=forms.TextInput(attrs={'type': 'date'}))

    class Meta:
        model = LeaveRequest
        fields = ['employee', 'type']

    def filter_employee(self, queryset, name, value):
        qs = queryset.filter(user=self.user).filter(**{name: value})
        if len(qs) >= 1:
            return qs[0]
        else:
            return None
0
ChrisRob 19 Feb. 2020 im 18:55

Ich habe nicht viel Erfahrung mit Django, aber ich sehe, dass Sie keine Metaattribute wie self.fields verwenden können. Sie müssen einen anderen Weg finden, dies zu tun.

Weitere Informationen zur Verwendung von Filtern finden Sie hier

0
Sanjay 19 Feb. 2020 im 15:05