SessionForm code question

Hi guys!

I’m curious as to what the following code inside indico.modules.events.sessions.forms.SessionForm’s __init__ method is supposed to do/take care of?

if event.type != 'conference':
    del self.code
    del self.type
else:
    self.type.query = SessionType.query.with_parent(event)
    if not self.type.query.has_rows():
        del self.type

I am trying to create an InvoiceForm, which is basically a copy of SessionForm (with changed text, etc.), but if I remove the above code from __init__, I get an Exception:

TypeError: ‘NoneType’ object is not callable

Stack:

Traceback (most recent call last):
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask/app.py", line 2463, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask/app.py", line 2449, in wsgi_app
    response = self.handle_exception(e)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask/app.py", line 1866, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask/app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask/app.py", line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask/app.py", line 1821, in handle_user_exception
    return handler(e)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask/app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask/app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask_pluginengine/util.py", line 194, in wrapped
    return func(*args, **kwargs)
  File "/home/user/dev/indico/src/indico/web/flask/util.py", line 84, in wrapper
    return obj().process()
  File "/home/user/dev/indico/src/indico/web/rh.py", line 275, in process
    res = self._do_process()
  File "/home/user/dev/indico/src/indico/web/rh.py", line 245, in _do_process
    rv = self._process()
  File "/home/user/dev/indico/plugins/my/invoices/indico_invoices/controllers.py", line 51, in _process
    return jsonify_form(form)
  File "/home/user/dev/indico/src/indico/web/util.py", line 78, in jsonify_form
    footer_align_right=footer_align_right, disable_if_locked=disable_if_locked)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/jinja2/runtime.py", line 575, in __call__
    return self._invoke(arguments, autoescape)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/jinja2/runtime.py", line 579, in _invoke
    rv = self._func(*arguments)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask_pluginengine/util.py", line 154, in decorator
    return func(*args, **kwargs)
  File "/home/user/dev/indico/src/indico/web/templates/forms/_form.html", line 619, in macro
    
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask_pluginengine/templating.py", line 108, in call
    return super(PluginJinjaContext, __self).call(__obj, *args, **kwargs)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/jinja2/runtime.py", line 575, in __call__
    return self._invoke(arguments, autoescape)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/jinja2/runtime.py", line 579, in _invoke
    rv = self._func(*arguments)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask_pluginengine/util.py", line 154, in decorator
    return func(*args, **kwargs)
  File "/home/user/dev/indico/src/indico/web/templates/forms/_form.html", line 418, in macro
    
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask_pluginengine/templating.py", line 108, in call
    return super(PluginJinjaContext, __self).call(__obj, *args, **kwargs)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/jinja2/runtime.py", line 575, in __call__
    return self._invoke(arguments, autoescape)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/jinja2/runtime.py", line 579, in _invoke
    rv = self._func(*arguments)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask_pluginengine/util.py", line 154, in decorator
    return func(*args, **kwargs)
  File "/home/user/dev/indico/src/indico/web/templates/forms/_form.html", line 382, in macro
    
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask_pluginengine/templating.py", line 108, in call
    return super(PluginJinjaContext, __self).call(__obj, *args, **kwargs)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/jinja2/runtime.py", line 575, in __call__
    return self._invoke(arguments, autoescape)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/jinja2/runtime.py", line 579, in _invoke
    rv = self._func(*arguments)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask_pluginengine/util.py", line 154, in decorator
    return func(*args, **kwargs)
  File "/home/user/dev/indico/src/indico/web/templates/forms/_form.html", line 220, in macro
    
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/flask_pluginengine/templating.py", line 108, in call
    return super(PluginJinjaContext, __self).call(__obj, *args, **kwargs)
  File "/home/user/dev/indico/src/indico/web/forms/jinja_helpers.py", line 91, in render_field
    return field(**args)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/wtforms/fields/core.py", line 155, in __call__
    return self.meta.render_field(self, kwargs)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/wtforms/meta.py", line 56, in render_field
    return field.widget(field, **render_kw)
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/wtforms/widgets/core.py", line 323, in __call__
    for val, label, selected in field.iter_choices():
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/wtforms/ext/sqlalchemy/fields.py", line 107, in iter_choices
    for pk, obj in self._get_object_list():
  File "/home/user/dev/indico/env/lib/python2.7/site-packages/wtforms/ext/sqlalchemy/fields.py", line 98, in _get_object_list
    query = self.query or self.query_factory()
TypeError: 'NoneType' object is not callable

Please don’t post unformatted or quote-formatted tracebacks. It’s very hard to read and looks incredibly messy. Tracebacks should be formatted as code, i.e. fenced in 3 backticks:

```
paste here
```

To answer your question, only “conference” events have session codes and session types, so we remove the fields from the form in other cases.

You usually do not need any __init__ in most forms. Anyway, if you want help with your code, please post that code :wink:

My bad :frowning: I just figured out how to make it “pretty print” the stack on the error page itself (by clicking the top bar of the DIV containing the exception stack)

OK, so if you have a query select field, then you indeed need to set the query attribute of that field inside the constructor to a SQLAlchemy query object that gets whatever you want the user to select from.

Hmm… is this some kind of “internal” form field?

type = QuerySelectField(_("Type"), get_label='name', allow_blank=True, blank_text=_("No type selected"))

It is not rendering in the browser, as far as I can tell?

It should be rendering as a dropdown labelled “Type”.

What do you actually want to do in your form?

Allow the user to create a new Invoice. I just randomly picked the SessionForm to learn from and use as the basis for my new InvoiceForm.

In that case get rid of the type field. You most likely don’t need/want it there.

Will do. I just noticed that there are no rows in the query associated with this field. Why is this so? How can one “add” rows to this query? I’m just curious

Thanks!

If it’s for session types that’d be done by using the “cog” menu on the session management page in a conference event and creating new session types there.

I think it’s actually here:

That’s another way of getting there. The cog menu next to “Sessions” has it as well.

Got it. Thanks, @ThiefMaster! The more I learn the internals of Indico, the more I love it :wink: