简体   繁体   中英

Override imported class variables - django/python

I need to override variables (or pass dynamic data) to imported class.

filters.py

import django_filters
from .models import Gate, Tram, OperationArea, Bogie
from distutils.util import strtobool
from django import forms


class GateFilter(django_filters.FilterSet):

    # Prepare dynamic lists with choices
    tram_list = [(id, number) for id, number in Tram.objects.all().values_list('id', 'number')]
    bogie_list = [(id, number) for id, number in Bogie.objects.all().values_list('id', 'number')]
    area_list = [(id, area) for id, area in OperationArea.objects.all().values_list('id', 'area')]
    # Generate fields
    tram = django_filters.MultipleChoiceFilter(choices=tram_list, label=u'Tramwaj')
    car = django_filters.MultipleChoiceFilter(choices=Gate.CAR_SYMBOLS, label=u'Człon')
    bogie = django_filters.MultipleChoiceFilter(choices=bogie_list, label=u'Wózek')
    bogie_type = django_filters.MultipleChoiceFilter(choices=Gate.BOGIE_TYPES, label=u'Typ wózka')
    area = django_filters.MultipleChoiceFilter(choices=area_list, label=u'Obszar')
    operation_no = django_filters.CharFilter(label=u'Numer operacji', widget=forms.TextInput(attrs={'size': '16px'}))
    status = django_filters.MultipleChoiceFilter(choices=Gate.GATE_STATUSES, label=u'Status')
    rating = django_filters.MultipleChoiceFilter(choices=Gate.GATE_GRADES, label=u'Ocena')

    class Meta:
        pass

views.py

from .filters import GateFilter

class GateListView(generic.ListView):

    queryset = None
    gate_type = None
    template_name = 'qapp/gate/list.html'
    context_object_name = 'gate_list'
    paginate_by = 20

    def get_queryset(self):
        # Type is stored in database as big-letter word, so 'bjc' != 'BJC'.
        if self.gate_type.upper() == 'BJW':
            ordering = ['bogie', 'bogie_type']
        else:
            ordering = ['tram', 'car']
        queryset = Gate.objects.filter(type=self.gate_type.upper()).order_by(*ordering)
        self.gate_list = GateFilter(self.request.GET, queryset=queryset)
        return self.gate_list.qs.distinct()

    def get_context_data(self, **kwargs):
        context = super(GateListView, self).get_context_data(**kwargs)
        # Return Gate.type to template.
        context['gate_type'] = self.gate_type
        # Return object (for generating form) to template.
        context['gate_list_filter'] = self.gate_list
        return context

As you can see, in the filters.py , the data for variables tram_list, bogie_list and area_list are dynamic (fetched from database).

But during importing this class to views.py, this data becomes static.

I tried to override this values:

  • using @classmethod decorator in class GateFilter , and calling it before setting self.gate_list object,
  • in views.py using GateFilter.tram_list (and the rest) notation,

No luck.

I can't use reload() function, due to import type ( from .filters import GateFilter ).

Currently for update lists in filters.py I need to rerun whole app. This is unacceptable for business logic of my app.

This is the wrong approach. Rather, you should be using the filters that are aware of querysets and that evaluate them when required: ModelChoiceFilter and ModelMultipleChoiceFilter.

class GateFilter(django_filters.FilterSet):
    team = django_filters.ModelMultipleChoiceFilter(queryset=Tram.objects.all())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM