Search code examples
djangodjango-formsdjango-users

How to render a form with a user's data?


How do I create a django form to display a user's sell objects with a radio box next to each obejct for deletion? I'm trying to create something similar to the django admin where users are listed with radio boxes for quick deletion.

django forms

From the request.user I'm trying to get the Sell's associated objects from a user and return a list of sells in order to delete the selected. So far my profile form looks like this:

class ProfileForm(ModelForm):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request")
        super(ProfileForm, self).__init__(*args, **kwargs)

    sells = forms.IntegerField(
        widget=forms.Select(
            sell=Sell.object.filter(user=self.request.uwer)
        )
    )

In the views.py I plan to delete selected sell objects like so:

for sell in form.sells:
    sell = Sell.objects.get(id=sell)
    sell.delete()

Solution

  • There's quite a few things wrong here. The most significant is that you can't set the choices in the form definition, as you don't have access to request.user there.

    I don't think you want a model form, anyway. Those are for creating and editing model instances, whereas you simply want to list existing instances with a checkbox. So you just want a normal form with a field that represents those instances, ie a ModelMultipleChoiceField.

    So, the form looks like this:

    class DeleteSellForm(forms.Form):
        sells = forms.ModelMultipleChoiceField(queryset=Sell.objects.none(),
                                               widget=forms.CheckboxSelectMultiple)
    
        def __init__(self, *args, **kwargs):
            user = kwargs.pop('user', None)
            super(DeleteSellForm, self).__init__(*args, **kwargs)
            self.fields['sells'].queryset=Sell.objects.filter(user=user)
    

    You'll notice that the queryset defaults to none, but is set to the correct user's objects in the __init__ method, where we can pass in the user.

    So the view looks like this:

    def delete_sells(request):
        if request.POST:
            form = DeleteSellsForm(request.POST, user=request.user)
            if form.is_valid():
                form.cleaned_data['sells'].delete()
        else:
            form = DeleteSellsForm(user=request.user)
        return render(request, 'template.html', {'form': form})
    

    ModelMultipleChoiceField cleans to a QuerySet, so you should be able to call delete() on it directly.