Django forms request.user

23,248

Solution 1

I think you can achieve this by overriding the __init__() method of the form, passing in an instance of User and filtering the queryset using that user. Something like this:

class TrophiesForm(ModelForm):
    used_his = forms.ModelMultipleChoiceField(queryset=Gun.objects.filter(user__id=1))

    def __init__(self, user, *args, **kwargs):
        super(TrophiesForm, self).__init__(*args, **kwargs)
        self.fields['used_his'].queryset = User.objects.filter(pk = user.id)

In your view you can pass in the appropriate (currently logged in) instance of User.

def my_trophies(request, *args, **kwargs):
    user = request.user
    form = TrophiesForm(user)
    ... 

Solution 2

Another angle to Manoj's submission ...

use a kwarg to pass user data, as to not mess with the method signature since it expects request.POST as the first argument. A better convention would be as follows.

class TrophiesForm(ModelForm):
    def __init__(self, *args, **kwargs):
        #using kwargs
        user = kwargs.pop('user', None)
        super(TrophiesForm, self).__init__(*args, **kwargs)
        self.fields['used_his'].queryset = User.objects.filter(pk = user.id)

Now in the call, this is more explicit and follows a better signature convention

form = TrophiesForm(request.POST, request.FILES, user=request.user)

You could also use instance: (note the super before you grab the instance obj)

class TrophiesForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(SubmissionUploadForm, self).__init__(*args, **kwargs)
        user = self.instance.user
        self.fields['used_his'].queryset = User.objects.filter(pk = user.id)

You can then call in your views.py like so:

form = TrophiesForm(instance=*MyModel*(user=request.user))
Share:
23,248

Related videos on Youtube

ApPeL
Author by

ApPeL

Engineer turned entrepreneur Co-Founder FundedByMe.com

Updated on September 22, 2020

Comments

  • ApPeL
    ApPeL over 3 years

    I my model users can create rifles and this rifle is obviously associated with a User.

    class Gun(ImageModel):
        user = models.ForeignKey(User)  
        ...  
        ...  
        ...
    

    I have another model which is dependent on this and need to make use of the users rifles, but when the user adds a record I only want to display his rifles.

    mt model looks as follows

    class Trophies(ImageModel):  
        used_his = models.ForeignKey(Gun)
    

    my form looks as follows

    from django.forms import ModelForm
    from django import forms
    from models import Trophies
    from gunsafe.models import Gun
    from django.contrib.auth.models import User
    
    class TrophiesForm(request.user, ModelForm):
        used_his = forms.ModelMultipleChoiceField(queryset=Gun.objects.filter(user__id=1))
    
        def __init__(self, user, *args, **kwargs):
            super(TrophiesForm, self).__init__(*args, **kwargs)
            self.fields['used_his'].queryset = User.objects.filter(pk = user)
    

    I was wondering how I can get the current logged in users ID instead of the user__id=1

    Here is the view.

    def edit(request, trophy_id, template_name='trophies/edit.html'):
        trophy = Trophies.objects.get(pk=trophy_id)
    
        if request.method == 'POST':
            form = TrophiesForm(request.POST, request.FILES, instance=trophy)
            if form.is_valid():
                newform = form.save(commit=False)
                newform.user = request.user
                newform.save()  
                ...  
                ...
    
  • ApPeL
    ApPeL over 13 years
    I amended some code and pasted the view in there. Based on this I still get an error. __init__() takes at least 2 arguments (1 given), maybe you can point out where I am going wrong with this. much appreciated
  • Manoj Govindan
    Manoj Govindan over 13 years
    @ApPel: can you pass the user instance as the first argument to the form's constructor and try again? form = TrophiesForm(request.user, ...).
  • ApPeL
    ApPeL over 13 years
    basedon the changes when I add request.user as the first argument I just get 'name "request" is not defined'
  • ApPeL
    ApPeL over 13 years
    @Manoj: Pasted the updated version for you. Thanks for your help btw!
  • Manoj Govindan
    Manoj Govindan over 13 years
    @ApPel: This line from your model is wrong. self.fields['used_his'].queryset = User.objects.filter(pk = user). The filter should be pk = user.id.
  • Manoj Govindan
    Manoj Govindan over 13 years
    @ApPel: This line in the view needs to change: form = TrophiesForm(request.POST, request.FILES, instance=trophy). Change to form = TrophiesForm(request.user, request.POST, request.FILES, instance=trophy)
  • Manoj Govindan
    Manoj Govindan over 13 years
    @ApPel: great :) Happy coding!

Related