Chained dropdown in registration

Hello, i’m new in django and openEdx, i want to create a chained dropdown in register page.
i already followed the tip for Create a Custom Registration Page, but i cant figure out how to make a chained dropdown, is there a way to do this?

thanks

1 Like

Hi! Could you provide an example of the desired behaviour? And some tech context would be cool also (OeX release at least).

Hi,

for example, i need to make a registration page that i can select State and City, but i need to filter the city options in dropdown based on the state selection. Only cities of selected state must appear in the city’s dropdown
Unfortunetly i can’t upload images =(

i’m running devstack from https://github.com/edx/devstack, i think that is the latest release of open edx, i don’t know, sorry =/

thanks

In your form file in CustomForm which should be https://github.com/open-craft/custom-form-app/blob/master/custom_reg_form/forms.py

what you can do is pass query to chain the form. Something like:

class ExtraInfoForm(forms.ModelForm):
    class Meta:
        model = ExtraInfo
        fields = (''country', 'city')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['city'].queryset = City.objects.none()

        if 'country' in self.data:
            try:
                country_id = int(self.data.get('country'))
                self.fields['city'].queryset = City.objects.filter(country_id=country_id).order_by('name')
            except (ValueError, TypeError):
                pass  # invalid input from the client; ignore and fallback to empty City queryset
        elif self.instance.pk:
            self.fields['city'].queryset = self.instance.country.city_set.order_by('name')

Given that you have data in your form. Have you tried this? I didn’t run the code above but I feel this can work.

Thank you for the response,

I have the data in my City model,

in models.py i have something like

    class ExtraInfo(models.Model):
        state = models.CharField(
            verbose_name="State",
            choices=STATE_CHOICES,
            max_length=100,
        )
        city = models.CharField(
            verbose_name="city",
            max_length=100,
        )

    class City(models.Model):
        name = models.CharField('City', max_length=100, blank=True)
        uf = models.CharField('UF', max_length=2, choices=STATE_CHOICES)

        def __str__(self):
            return self.name

        class Meta:
            ordering = ('name',)
            verbose_name = 'city'
            verbose_name_plural = 'cities'

i wrote the snippet that you sent, but no difference (the good news are that there were no errors), have i to make city in models.py a ForeingKey?

STATE_CHOICES coming from django localflavor

I made city in models.py be ForeignKey and gave the error:

ImproperlyConfigured at /register
Field type 'None' not recognized for registration extension field 'city'.
Request Method:	GET
Request URL:	http://localhost:18000/register
Django Version:	2.2.16
Exception Type:	ImproperlyConfigured
Exception Value:	
Field type 'None' not recognized for registration extension field 'city'.
Exception Location:	/edx/app/edxapp/edx-platform/openedx/core/djangoapps/user_authn/views/registration_form.py in get_registration_form, line 399
Python Executable:	/edx/app/edxapp/venvs/edxapp/bin/python
Python Version:	3.8.6
Python Path:	
['/edx/app/edx_ansible/edx_ansible/docker/plays',
 '/edx/app/edxapp/edx-platform',
 '/edx/app/edxapp/venvs/edxapp/lib/python38.zip',
 '/edx/app/edxapp/venvs/edxapp/lib/python3.8',
 '/edx/app/edxapp/venvs/edxapp/lib/python3.8/lib-dynload',
 '/usr/lib/python3.8',
 '/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages',
 '/edx/app/edxapp/venvs/edxapp/src/acid-xblock',
 '/edx/app/edxapp/venvs/edxapp/src/codejail',
 '/edx/app/edxapp/venvs/edxapp/src/django-wiki',
 '/edx/app/edxapp/venvs/edxapp/src/done-xblock',
 '/edx/app/edxapp/venvs/edxapp/src/edx-jsme',
 '/edx/app/edxapp/venvs/edxapp/src/rate-xblock',
 '/edx/app/edxapp/venvs/edxapp/src/xblock-google-drive',
 '/edx/app/edxapp/edx-platform/common/lib/capa',
 '/edx/app/edxapp/edx-platform',
 '/edx/app/edxapp/edx-platform/common/lib/safe_lxml',
 '/edx/app/edxapp/edx-platform/common/lib/sandbox-packages',
 '/edx/app/edxapp/edx-platform/common/lib/symmath',
 '/edx/app/edxapp/edx-platform/openedx/core/lib/xblock_builtin/xblock_discussion',
 '/edx/app/edxapp/edx-platform/common/lib/xmodule',
 '/edx/src/apice-registration',
 Path('/edx/app/edxapp/edx-platform'),
 Path('/edx/app/edxapp/edx-platform/sys_path_hacks/lms'),
 Path('/edx/app/edxapp/edx-platform/common/djangoapps')]
Server time:	Thu, 29 Oct 2020 20:14:38 +0000

Looks like error is because of your form as it is not able to except blank as answers i.e None being set.

city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True)

Perhaps this might help?

i don’t know what i’m doing wrong, but if i declare

city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True)

appers the message undefined name ‘City’ in my IDE, and if a run migrations the same message appers.

is there an way to call City class in models.py?

if i wrote

city = models.ForeignKey('City', on_delete=models.SET_NULL, null=True)

the message ‘None’ keeps

i fixed the City and ‘City’ problem.

same error ‘None’ continues

can someone help me? I haven’t yet

Add
forms.ModelChoiceField: "select",
in FIELD_TYPE_MAP in /edx-platform/openedx/core/djangoapps/user_api/helpers.py at line 107

2 Likes

It’s Working for me also. Thank You.