Arundeep Chohan
Arundeep Chohan

Reputation: 9969

Django queryset for user

models.py(shrunk to things that matter)

class Messages(models.Model):
    sender = models.ForeignKey(Profile,related_name='sender',on_delete=models.CASCADE)
    receiver = models.ForeignKey(Profile,related_name='receiver',on_delete=models.CASCADE)

forms.py

class MessageForm(forms.ModelForm):
    subject = forms.CharField(max_length=100, required=False, help_text='Optional.')
    text = forms.CharField(max_length=4096, required=True, help_text='Required.')
    class Meta:
        model = Messages
        fields = ('receiver','subject','text',)

I have a dropdown that shows all users that were made I would like to filter it based off some fields like is_active to showcase only users that are authenticated and more like this so I would like to override I think it's receiver queryset.

def index(request):

    sendMessageForm = MessageForm()


if is_staff:
   if is_active:
else:

What my current form displays.

<select name="receiver" required="" id="id_receiver">
  <option value="" selected="">---------</option>

  <option value="39">1</option>

  <option value="40">2</option>

  <option value="41">3</option>

  <option value="42">4</option>

</select>

Upvotes: 0

Views: 113

Answers (1)

Swift
Swift

Reputation: 1711

You can override the queryset of the field in the init of the form like so:

class MessageForm(forms.ModelForm):
    subject = forms.CharField(max_length=100, required=False, help_text='Optional.')
    text = forms.CharField(max_length=4096, required=True, help_text='Required.')
    class Meta:
        model = Messages
        fields = ('receiver','subject','text',)

    def __init__(self, *args, user=None, **kwargs):
        user = kwargs.pop('user')  # use this for your filter
        super().__init__(*args, **kwargs)
        self.fields['receiver'].queryset = Profile.objects.filter(...)

Therefore updating the available choices in the drop down when the form is rendered.

Maybe on your profile you have a friends list, which is a M2M to itself, and you want to filter only user profiles which are on the senders friend list. This would be a use case for the above code.

You can also explicitly declare the field like so:

receiver = forms.ModelChoiceField(queryset=Profile.objects.filter(...))

Note: using this method you would not be able to use request.user so this would not be valid for you.

And as per your comment, to allow you to access request.user within the init funtion:

def index(request):
    sendMessageForm = MessageForm(user=request.user)

As an added bonus, we always use snake case for variables in python. So your variable should be send_message_form and furthermore, if its the only form on the page, why not just shorten that variable to form ?

Upvotes: 1

Related Questions