2

I have a semi large software. At one point I included tables2 into that project and started to work with it. I the filter.py file I included some basic Model filtering. Now if I delete my database and try to run a fresh migrations I get the error, that this table is not avaible. I builded a try catch around and it's working since it does not run the code snipped before the migration.

class PracticephaseProjectFilter(django_filters.FilterSet):
    omni = django_filters.CharFilter(method=omni_search, label="Suche")
    practice_phase = django_filters.ModelChoiceFilter(queryset=PracticePhase.objects.filter(pk__in=get_pp_for_specialpermit()))

    class Meta:
        model = PracticePhaseProject
        fields = ['practice_phase']

    def __init__(self, *args, **kwargs):
        super(PracticephaseProjectFilter, self).__init__(*args, **kwargs)
def get_pp_for_specialpermit():
    pp = []
    today = date.today()
    # check if SS or WS required
    if 4 <= today.month <= 9:
        # current SS, project will be sought for WS this year
        pp_str = [str(today.year)[-2:] + "s", str(today.year - 1)[-2:] + "w"]
    # we are in WS, check correct year for SS
    elif today.month > 9:
       pp_str = [str(today.year)[-2:] + "w", str(today.year)[-2:] + "s"]
    # we are allready in the year of next SS
    else:
        pp_str = [str(today.year - 1)[-2:] + "s", str(today.year - 1)[-2:] + "w"]
    try:
        for _pp in PracticePhase.objects.filter(semester__name__in=pp_str):
            pp.append(_pp.pk)
    except:
        pass
    return pp

Now if I remove the try catch around the for loop I cannot run the migrations since I get on database error that there is no table practicephase. But the file should never be called before migration.

Dominic M.
  • 273
  • 1
  • 5
  • 15

1 Answers1

2

The system checks framework runs before the makemigrations and migrate commands run.

The URL checks cause your urls.py to be imported, which loads your module containing PracticephaseProjectFilter.

You shouldn't call get_pp_for_specialpermit in the filterset definition - it means that the query will run once when the server starts. This means you have an unnecessary query before the Django server is ready, and the result might be stale later on.

You can prevent the query from running by moving the queryset into the __init__ method:

class PracticephaseProjectFilter(django_filters.FilterSet):
    omni = django_filters.CharFilter(method=omni_search, label="Suche")
    practice_phase = django_filters.ModelChoiceFilter(queryset=PracticePhase.objects.none())

    class Meta:
        model = PracticePhaseProject
        fields = ['practice_phase']

    def __init__(self, *args, **kwargs):
        super(PracticephaseProjectFilter, self).__init__(*args, **kwargs)
        self.filters['practice_phase'].queryset = PracticePhase.objects.filter(pk__in=get_pp_for_specialpermit())
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • Just for your interessted: It worked! Thank you for your answer. For ModelChoiceFilter it looks as following: `self.filters['practice_phase'].queryset = PracticePhase.objects.filter(pk__in=get_pp_for_specialpermit())` – Dominic M. Aug 02 '19 at 14:04
  • @DominicM. glad it worked. I've updated the `__init__` method with the correct code. – Alasdair Aug 02 '19 at 14:09