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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With