简体   繁体   中英

Django form received wrong data from request.POST

I added a filter to my form, so that it only displays the options that belong to the user when request.GET, everything works fine at first, but next time it runs, something goes wrong. It shows the 'QueryDict' object has no attribute 'id' error, so by checking, I found that the user variable in the form received the data sent by request.POST . This should not happen, I guess? Here is my code

Views.py

@login_required
@transaction.atomic
def update_profile(request):
    if request.method == 'POST':
        profile_form = ProfileForm(request.POST,instance=request.user.profile)
        if profile_form.is_valid():
            profile_form.save()
            messages.success(request,_('success!'))
            return redirect('character-manage')
        else:
            messages.error(request,_('something is wrong.'))
    else:
        profile_form = ProfileForm(instance=request.user.profile,user=request.user)
    return render(request,'corp/profile.html',{
        'profile_form':profile_form
    })

Forms.py

class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ('pcharacter',)
    def __init__(self,user=None,**kwargs):
        super(ProfileForm,self).__init__(**kwargs)
        if user:
            self.fields['pcharacter'].queryset = EveCharacter.objects.filter(bounduser=user)

When I add print(user) under the __init__ function, refresh the form page and I will get a user object, but when I submit the form it will show something like this <QueryDict: {'csrfmiddlewaretoken': ['*****'], 'pcharacter': ['2']}> What went wrong? Any suggestions or guidance are appreciated.

In the init() for form, if user, i am not sure what you are trying to achieve, i guess some logic is wrong. Can you try changing this and check again.

The issue comes from this line.

profile_form = ProfileForm(request.POST,instance=request.user.profile)

You are passing request.POST as the first argument. This is then being interpreted the same as if you wrote this...

profile_form = ProfileForm(user=request.POST,instance=request.user.profile)

The first positional argument in a ModelForm is data . That is why you can pass request.POST as a positional argument without writing data=request.POST .

To fix this you need to change your __init__() function to be operable with the __init__() function your form class is inheriting from.

I would recommend something like this...

def __init__(self, *args, **kwargs):
    super(ProfileForm,self).__init__(**kwargs)
    if 'user' in kwargs:
       self.fields['pcharacter'].queryset = EveCharacter.objects.filter(
           bounduser=kwargs.get('user')
       )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM