3

I do not want the logged in user to show up on this ModelMultipleChoiceField in order to restrict themselves from creating a following relationship with themselves? So how do I exclude the logged in user from the queryset, probably an easy fix but I'm new to Django and it has eluded me for a few hours now.

forms.py

class Add_Profile(forms.ModelForm):

def __init__(self,*args, **kwargs): # initializing your form in other words loading it
    super(Add_Profile, self).__init__(*args, **kwargs)
    user_id = kwargs.pop('user_id') # taking user_id out of the querylist
    self.fields['follows'] = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(), queryset=UserProfile.objects.filter(~Q(id=user_id)))

  class Meta:
     model = UserProfile
     fields = (
        'bio',
        'follows',
        'theme',
        'profile_picture',
     )

Views.py

@login_required   
def edit_profile(request, user_id):
userprofile = UserProfile.objects.get(pk=user_id)
if request.method == 'POST':
    edit_profile = Add_Profile(request.POST, request.FILES, instance=userprofile, user_id=request.user.id)
    if edit_profile.is_valid():
        edit_profile.save()
        return redirect('/home/user/{0}/'.format(request.user.username))
    else:
        print edit_profile.errors
else:
    edit_profile = Add_Profile(instance=userprofile, user_id=request.user.id)
return render (request, 'edit.html', {'form': edit_profile,})

Error: init() got an unexpected keyword argument 'user_id'

  • possible duplicate of [Django ModelChoiceField: filtering query set and setting default value as an object](http://stackoverflow.com/questions/5329586/django-modelchoicefield-filtering-query-set-and-setting-default-value-as-an-obj) – Leistungsabfall Aug 12 '15 at 19:25

2 Answers2

2

You can definitely do it using forms.Form instead of forms.ModelForm with something along the lines of this example in the docs:

from django import forms
from django.contrib.auth import get_user_model

class Add_Profile(forms.Form):
    follows = forms.ModelMultipleChoiceField(queryset=None)

    def __init__(self, user=None, *args, **kwargs):
        super(Add_Profile, self).__init__(*args, **kwargs)
        if user is not None:
            self.fields['follows'].queryset = get_user_model().objects.exclude(pk=user.pk)
        else:
            self.fields['follows'].queryset = get_user_model.objects.all()

Just pass in the user you wish to exclude when you instantiate the form:

form = Add_Profile()  # all users will be present in the dropdown
some_guy = User.objects.get(pk=4)
form = Add_Profile(user=some_guy)  # all users except some_guy will be present
chucksmash
  • 5,777
  • 1
  • 32
  • 41
  • Anyway you could show me how to write the view I always use models forms would the view look any different, using a regular form like this. –  Aug 12 '15 at 22:16
  • @appa_lover Everything in the view looks the same when calling a Form instead of a ModelForm usually. This case is an exception because we have added a parameter to the `__init__` method signature. Instead of calling it like `f = Add_Profile()`, you'll call it like `f = Add_Profile(user=request.user)` if the user is logged in. – chucksmash Aug 12 '15 at 23:52
  • @appa_Iover oh and I left out the rest of the field definitions on the `forms.Form`. You'll need to define each of the fields you want to use there as well. – chucksmash Aug 12 '15 at 23:53
1

Define an __init__ method for the form class. Pass the logged in userid to the form while initializing it, this will work with a model form.

def __init__(self, *args, **kwargs):
    user_id = kwargs.pop('user_id')
    super(Add_Profile, self).__init__(*args, **kwargs)
    self.fields['follows'] = forms.ModelMultipleChoiceField(queryset=UserProfile.objects.filter(~Q(user_id=user_id)))

While initializing your form, you can pass user_id

address_form = Add_Profile(request.POST, user_id=request.user.id)
anupsabraham
  • 2,781
  • 2
  • 24
  • 35
  • 1
    what does that ~Q do? –  Aug 13 '15 at 17:31
  • 2
    `Q()` is a query object. You can read more about it [here](https://docs.djangoproject.com/en/1.7/ref/models/queries/#q-objects) . Adding `~` is like doing a negative operation. You can also replace the queryset expression with `UserProfile.objects.exclude(id=user_id)`. – anupsabraham Aug 13 '15 at 17:42
  • I'm getting a keyword argument if I edit my question you think you could help me out, I think it is an issue with my view? –  Aug 13 '15 at 17:47
  • Please edit the question and let me know more about the issue. – anupsabraham Aug 13 '15 at 17:49
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/86914/discussion-between-anupsabraham-and-appa-lover). – anupsabraham Aug 13 '15 at 17:50