[Fixed]-Auth select chooses in forms.py

1đź‘Ť

âś…

Whenever you instantiate your form inside your view, you should pass the user object, like this my_form = MyModelForm(user=request.user).

Then build your MyModelForm:

# forms.py

from django.forms import ModelForm
from django.forms.widgets import Select

class MyModelForm(ModelForm):
    def __init__(self, *args, **kwargs):
        # extract "user" value from kwrags (passed through form init). If there's no "user" keyword, just set self.user to an empty string.
        self.user = kwargs.pop('user', '')
        super(MyModelForm, self).__init__(*args, **kwargs)
        if self.user:
            # generate the choices as (value, display). Display is the one that'll be shown to user, value is the one that'll be sent upon submitting (the "value" attribute of <option>)
            choices = MyModel.objects.filter(user=self.user).values_list('id', 'upload')
            self.fields['upload'].widget = Select(choices=choices)

    class Meta:
        model = MyModel
        fields = ('upload',)

Now, whenever you instantiate the form with a user keyword argument (my_form = MyModelForm(user=request.user)), this form will be rendered like this (in your template write it like {{ my_form }}):

<select>
    <option value="the_id_of_the_MyModel_model">upload_name</option>
    <option value="the_id_of_the_MyModel_model">upload_name</option>
    ...
</select>

Finally, in order to display images in the dropdown menu (remember, “value” is the one that will be sent back to server upon submiting the form, while the display one just for the UX), take a look here.

[UPDATE]: How to do it in your views.py

# views.py

def my_view(request):
    my_form = MyModelForm(user=request.user)
    if request.method == 'POST':
        my_form = MyModelForm(request.POST, user=request.user)
        if my_form.is_valid():
            # ['upload'] should be the name of the <select> here, i.e if <select name="whatever"> then this should be "whatever"
            pk = my_form.cleaned_data['upload']
            # image, now, is the value of the option selected (that is, the id of the object)
            obj = MyModel.objects.get(id=pk)
            print(obj.upload.url)  # this should print the image's path
    return render(request, 'path/to/template.html', {'my_form': my_form})
👤nik_m

Leave a comment