1

I am creating a form in django, hoping to allow users to delete some of their devices. When I click on the submit button of my form, I keep getting the message: Select a valid choice. <Some choice> is not one of the available choices. Here is my code. Thanks a lot :)

forms.py

class DeleteDeviceForm(forms.Form):
    devices = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple)

views.py

def delete_device(request):
    if request.method == 'POST':
        deletedeviceform = DeleteDeviceForm(request.POST)
        if deletedeviceform.is_valid():
            devicelist = request.POST.getlist('devices')
#will put other stuff there to process the data later, just want to access list now
            return HttpResponseRedirect('/accounts/loggedin', {"devicelist": devicelist, })

    else: #if not a POST request 
        userid = request.user.profile.pk
        devices = Device.objects.filter(user_id=userid)
        deletedeviceform = DeleteDeviceForm()
        deletedeviceform.fields['devices'].choices = [(x.id, x) for x in devices]

    return render(request, 'userprofile/delete_device.html', {"full_name": request.user.username, "deletedeviceform": deletedeviceform,})

Note that: I don't have a model for this form

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
Rose
  • 2,619
  • 4
  • 20
  • 27

3 Answers3

3

Thanks to @Daniel Roseman, I was able to figure it out.

Here is how I changed my code :

forms.py

class DeleteDeviceForm(forms.Form):
    devices = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,label="Select the devices you want to delete:")

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super(DeleteDeviceForm, self).__init__(*args, **kwargs)
        self.fields['devices'].choices = [(x.id, x) for x in Device.objects.filter(user_id=user)]

views.py

changed only one line to :

deletedeviceform = DeleteDeviceForm(request.POST, user=request.user.profile.pk)
Community
  • 1
  • 1
Rose
  • 2,619
  • 4
  • 20
  • 27
2

You've set the list of valid choices on the GET request only. On the POST, there are no choices, so the field can never be valid.

That code should go in the form's __init__ method, so it is run every time the form is instantiated.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Ok thanks for the advice, thats a great starting point ! :) however, I know I should have something that ressembles this : def __init__(self, *args, **kwargs): super(DeleteDeviceForm, self).__init__(*args, **kwargs) self.queryset = Device.objects.filter(user_id= ????) I don't know how am I supposed to get my user id inside that form... Any suggestion on how I could code this ? Thanks a lot :) – Rose Jul 14 '16 at 20:42
  • 1
    You need to pass it in from the view, and get it from *args or **kwargs. – Daniel Roseman Jul 14 '16 at 21:17
0

You can use very simple way in which you just have to update model not form. Use django-multiselectfield

pip install django-multiselectfield

Check here for reference https://pypi.org/project/django-multiselectfield/

Nids Barthwal
  • 2,205
  • 20
  • 12