Migration clashes with forms.py

前端 未结 5 536
轮回少年
轮回少年 2020-12-11 05:12

The command python manage.py makemigrations fails most of time due to the forms.py, in which new models or new fields are referenced at class defin

相关标签:
5条回答
  • 2020-12-11 05:40

    I was having this same issue and found the specific problem. When the migrate command was being called, Django's system checks made their way into my forms.py and then would fail when they encountered a line of code that made a query against a table that the migration was supposed to create. I had a choicefield that instantiated the choices with a database query like this:

    university = forms.ChoiceField(
        choices=[('', '')] + [(university.id, university.name) for university in University.objects.all()],
        widget=forms.Select(
            attrs={
                'class': 'form-control',
                'placeholder': 'University',
            }
        ),
        required=True
    )
    

    The solution was to remove the query from choices (leaving it just as [('', '')] and then populate the choices in the class's init method instead.

    class UniversityForm(forms.Form):
    
        university = forms.ChoiceField(
            choices=[('', '')],
            widget=forms.Select(
                attrs={
                    'class': 'form-control',
                    'placeholder': 'University',
                }
            ),
            required=True
        )
    
    
    def __init__(self, *args, **kwargs):
        super(UniversityForm, self).__init__(*args, **kwargs)
    
        # Load choices here so db calls are not made during migrations.
        self.fields['university'].choices = [('', '')] + [(university.name, university.name) for university in University.objects.all()]
    
    0 讨论(0)
  • 2020-12-11 05:52

    Exclude the new columns with .only in your query like this:

    University.objects.only('id', 'name').all()
    

    Then run your migration.

    0 讨论(0)
  • 2020-12-11 05:56

    Thanks to @alasdair I understood my problem and found a workaround: I replace the original code in the views.py file

    from MyApp import forms
    

    with

    import sys
    if 'makemigrations' not in sys.argv and 'migrate' not in sys.argv:
        from MyApp import forms
    

    It works fine in my case, but I suppose there is a better way to know if the current process is a migration or not. If so, please advise.

    0 讨论(0)
  • 2020-12-11 05:57

    I had a similar issue with ModelChoiceField in one of my forms. I had to comment out my forms code in order to be able to make migrations.

    For me the solution was to move all form imports into their respective view method in views.py.

    before:

    from .forms import CalculatorForm
    
    def calculator(request):            
        if request.method != 'POST':
            form = CalculatorForm()
            # ...
    

    after:

    def calculator(request):
        from .forms import CalculatorForm
        if request.method != 'POST':
            form = CalculatorForm()
            # ...
    
    0 讨论(0)
  • 2020-12-11 05:59

    init via callable...

    def get_provinces():
    province_choices = []
    for province in ProvinceCode.objects.filter(country_code_id=1).order_by('code'):
        province_choices.append((province.code, province.code))
    return province_choices
    
    class MemberForm(forms.Form):
        provinces = forms.ChoiceField(label='Provinces', 
        choices=get_provinces, required=True)
    

    Refer here - Django relation error when running make migrations

    0 讨论(0)
提交回复
热议问题