Home > OS >  Fill a ChoiceField in Django template with external data
Fill a ChoiceField in Django template with external data

Time:02-17

I'm new to Django and I'm having a hard time understanding forms when the data to choose from are not taken from the database nor user input that they're generated on the go.

I currently have a template with a single ChoiceField. The data inside this field aren't fixed and they're calculated on the go once the page is requested. To calculate it I need the username of the User who is logged in. Basically, the calculation returns a list of lists in the form of ((title, id),(title,id),(title,id)), etc. that I need to put into the ChoiceField to make the User choose from one of the options.

Now, I'm not understanding how to pass the calculated list of lists to the form. I've tried to add the calculations inside the form as below but it is clearly the wrong way.

The main issue is that, to calculate my list of lists, I need the request value, and I don't know how to access it from the form.

Another idea was to add the generate_selection function inside the init but then I don't know how to pass main_playlist to being able to add it to ChoiceField

Below my not working forms.py

forms.py

class ChoosePlaylistForm(forms.Form):

    playlists = forms.ChoiceField(choices=HERE_SHOULD_GO_main_playlist)

    def generate_selection(self):
        sp_auth, cache_handler = spotify_oauth2(self.request)
        spotify = spotipy.Spotify(oauth_manager=sp_auth)
        user_playlists = spotify.current_user_playlists(limit=10)

        main_playlist = []
        for playlists in user_playlists["items"]:
            playlists_list = []

            playlists_list.append(playlists['name'])
            playlists_list.append(playlists['id'])
            main_playlist.append(playlists_list)

        return main_playlist

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(ChoosePlaylistForm, self).__init__(*args, **kwargs)

    class Meta:
        model = User
        fields = ('playlists',)

The views should be something like below so I'm able to pass the request

views.py

form = ChoosePlaylistForm(request=request)

CodePudding user response:

Maybe overriding the field choices in the form constructor would work:

class ChoosePlaylistForm(forms.Form):
    playlists = forms.ChoiceField(choices=())

    class Meta:
        model = User
        fields = ('playlists',)

    def __init__(self, *args, request=None, **kwargs):
        super(ChoosePlaylistForm, self).__init__(*args, **kwargs)
        self.request = request
        self.fields['playlists'].choices = self.generate_selection()

    def generate_selection(self):
        sp_auth, cache_handler = spotify_oauth2(self.request)
        spotify = spotipy.Spotify(oauth_manager=sp_auth)
        user_playlists = spotify.current_user_playlists(limit=10)

        choices = []
        for playlist in user_playlists["items"]:
            playlist_choice = (playlist["name"], playlist["id"])
            choices.append(playlist_choice)

        return choices
  • Related