oTree Forum >

Problem with {form_field}_choices()

#1 by manuela

Hi,

Problem: {form_field}_choices() does not work for me. I always receive an error message. Can you help me find out what is going wrong?


Context:
I plan to dynamically assign choice values to my multiple-choice questions.

Thus, I have been following these instructions: https://otree.readthedocs.io/en/latest/forms.html?highlight=formfield%20label#formfield
It didn't work with my specific MCQ but I can also not make the example from the otree documentation work:

__init__.py
from otree.api import (
	models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer
)

class Player(BasePlayer):
    fruit = models.IntegerField(widget=widgets.RadioSelect, blank=True)

    def fruit_choices(player):
        import random
        choices = ['apple', 'kiwi', 'mango']
        random.shuffle(choices)
        return choices

# PAGES
class Page1(Page):
    form_model = "player"
    form_fields = ["fruit"]

page_sequence = [Page1]

Page1.html
{{ block title }}
    Page title
{{ endblock }}
{{ block content }}

    {{ formfields }}
    {{ next_button }}

{{ endblock }}
    
Once I run otree devserver and open this game, the following error occurs: 
 Application error (500)
Exception: Field uses a radio/select widget but no choices are defined


oTree version: 
I tried this with oTree version 5.8.4 and 5.7.2.

#2 by ccrabbe

Hi Manuela -

This is a subtle one, I think.  I've done this before.  You're defining your fruit_choices() as a method of your Player class, where in the documentation it's just a function outside of the Model classes:

https://otree.readthedocs.io/en/latest/forms.html?highlight=formfield%20label#field-name-choices

You just need to un-indent that whole method once and it will probably work.

Thanks,
--Chris

#3 by manuela

Yes, that did the trick. 
Thank you so much, Chris!

#4 by arroycal

Hello,

I'm trying the same, have tried putting the {form_field}_choices() outside of the former pages.py and the player class but it's giving me an "internal server error". 

Any clue of why this may be?

Thank you

My code is as follows:

class Player(BasePlayer):
    reverse_side = models.IntegerField()
    riskychoice = models.IntegerField(
        widget=widgets.RadioSelectHorizontal,
        label='Which option do you prefer?'
    )

def riskychoice_choices(player):
    if player.reverse_side == 0:
        choices = [
                      [0, "Option 1"],
                      [1, "Option 2"],
                  ],
    if player.reverse_side == 1:
        choices = [
                      [1, "Option 1"],
                      [0, "Option 2"],
                  ],
    return choices

#5 by arroycal

In case this helps anybody in the future, what was preventing my code from working were the commas after the "choices = []". I.e., "choices = []," should be "choices = []".

Write a reply

Set forum username