Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask Form with parameters

I am trying to define a Flask form with one parameter. This was my approach:

forms.py

class RegisterPatternForm(FlaskForm):
    cursorPatients = MongoClient('localhost:27017').myDb["coll"].find({"field1": self.myParam}).sort([("id", 1)])
    patientOpts = []
    for pt in cursorPatients:
        row = (str(pt.get("id")), "{} {}, {}".format(pt.get("surname1"), pt.get("surname2"), pt.get("name")))
        patientOpts.append(row)

    patients = SelectMultipleField('Select the patient', validators=[Optional()], choices=patientOpts)
    submit = SubmitField('Register')

    def __init__(self, myParam, *args, **kwargs):
        super(RegisterPatternForm, self).__init__(*args, **kwargs)
        self.myParam = myParam

routes.py

myParam = 5
form = RegisterPatternForm(myParam)

Basically, I want to read the variable myParam defined on routes.py on the form RegisterPatternForm. The insertion of the param in routes.py works, as well as the __init__ method in RegisterPatternForm. Where it fails is when reading the field on the line that starts with cursorPatients.

Therefore, my question is, how can I solve this problem in order to be able to read myParam value inside the form?

like image 753
qwerty Avatar asked Nov 06 '22 10:11

qwerty


1 Answers

About problem.

cursorPatients / patients / etc is a class-level variable(static variable). It means you do not have instance and properties at this level. Roughly speaking, You trying to use self to access to an object but object was not created.

If I understood correctly you need to change some choices using a Form property.

Let's trying to change choices using __init__:

class RegisterPatternForm(FlaskForm):
    patients = SelectMultipleField('Select the patient',
                                   validators=[Optional()],
                                   choices=[('one', 'one')])

    def __init__(self, patients_choices: list = None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if patients_choices:
            self.patients.choices = patients_choices

RegisterPatternForm()  # default choices - [('one', 'one')]
RegisterPatternForm(patients_choices=[('two', 'two')])  # new choices

As you can see patients choices are changing using constructor. So in your case it should be something like this:

class RegisterPatternForm(FlaskForm):
    patients = SelectMultipleField('Select the patient',
                                   validators=[Optional()],
                                   choices=[])

    def __init__(self, myParam: int, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.myParam = myParam
        self.patients.choices = self._mongo_mock()

    def _mongo_mock(self) -> list:
        """
        db = MongoClient('localhost:27017').myDb["coll"]
        result = []
        for pt in db.find({"field1": self.myParam}).sort([("id", 1)]):
            blablabla....
        return result
        Just an example(I `mocked` mongo)
        """
        return [(str(i), str(i)) for i in range(self.myParam)]


form1 = RegisterPatternForm(1)
form2 = RegisterPatternForm(5)
print(form1.patients.choices)  # [('0', '0')]
print(form2.patients.choices)  # [('0', '0'), ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4')]

Hope this helps.

like image 177
Danila Ganchar Avatar answered Nov 12 '22 13:11

Danila Ganchar