0

Looking at the view code, to me it looks like the form class should be initialized everytime a GET is performed.

#views.py
if request.method == 'GET':
    form = PrenotaForm()
    return render(request, "prenota.html", {'form': form, 'posti_liberi': posti_disponibili, 'giovani_iscritti': giovani_iscritti})
else:
    # it's a POST

The thing I would figure out is why my code into the form class does not look to be executed at every refresh:

# forms.py
class PrenotaForm(forms.ModelForm):
    size_gruppi = 30
    print("gruppi size is : " + str(size_gruppi))

In my console I see that the code is executed everytime i modify and save the forms.py file, or whenever I start the server with python manage.py runserver:

Performing system checks...

gruppi size is : 30

But simple refreshes of the interested page does not execute the code as shown in console:

Django version 2.1, using settings 'test_project.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C. [24/May/2019 15:35:38] "GET /it/iscrizione/prenota/ HTTP/1.1" 200 11898 [24/May/2019 15:35:38] "GET /static/images/favicon.ico HTTP/1.1" 200 549 [24/May/2019 15:35:39] "GET /it/iscrizione/prenota/ HTTP/1.1" 200 11898 [24/May/2019 15:35:39] "GET /static/images/favicon.ico HTTP/1.1" 200 549 [24/May/2019 15:35:39] "GET /it/iscrizione/prenota/ HTTP/1.1" 200 11898 [24/May/2019 15:35:39] "GET /static/images/favicon.ico HTTP/1.1" 200 549

It is causing me problems because the form is not always updated (eg.: a dynamic choice DDL) triggering validation errors.

There is something wrong in my approach / code , or it is the normal behavior of django MTV / MVC pattern?

What can I do in order to update the form at every page refresh?

lese
  • 539
  • 1
  • 5
  • 24

1 Answers1

1

In python, class attributes (also called "class members") are associated with the class when reading the file. So size_gruppi is set when your file is imported the first time. When you instantiate a class (PrenotaForm()), the class' __init__() method is called. The instance will have the same attribute as the class unless you override it.

So if you want to change some attribute when instantiating the class, add the initialiser:

class PrenotaForm(ModelForm):
    size_gruppi = 30

    def __init__(self, *args, **kwargs):
        self.size_gruppi = kwargs.pop('size_gruppi', self.size_gruppi)
        super().__init__(*args, **kwargs)

# in your view
form = PrenotaForm(size_gruppi=50)  # form.size_gruppi = 50
form = PrenotaForm()  # form.size_gruppi = 30

So here I can override the attribute by passing it to the initialiser. If I don't pass it, the default value is retained.

dirkgroten
  • 20,112
  • 2
  • 29
  • 42
  • 1
    Good answer, except that class variables aren't set in `__new__()`; that method is also called on instantiation, not on definition. – Daniel Roseman May 24 '19 at 17:07