Ibo
Ibo

Reputation: 4309

Filter drop-down options in a django form based on logged-in user

I have a django form to create a new instance (record) of a class called Ticket. The users can be from different clients so I need to limit the options displayed in the drop-downs to the logged-in user's client basically. client is an attribute of a class that I have defined in admin.py, which defines the client name of the user. I know that I am on the right path, but I have a difficult making this work since I need to extract the client of the logged-in User and then use it to filter the fields (for example business) when initializing the form, any help would be appreciated? Please consider that I have multiple fields that should be filtered so if there is a way to do this once for all of the fields it would be great:

models.py

class Business(models.Model):
    client=models.ForeignKey('Client',on_delete=models.CASCADE, limit_choices_to={'is_active':True},)
    name=models.CharField(max_length=30,blank=False, unique=True,)
    description = models.CharField(max_length=50, blank=True, )
    is_active=models.BooleanField(default=True,)



class Ticket(MMRequestAttributes):    
    no=models.CharField('Ticket Number',max_length=50,default=uuid.uuid4,null=False, blank=False, editable=False, unique=True)
    subject=models.CharField('Subject',max_length=100,null=False, blank=False)
    business=models.ForeignKey('Business', on_delete=models.CASCADE,limit_choices_to={'is_active':True},)

    class Meta:
        permissions=(('view_ticket','Can see tickets'),)

views.py

def new_ticket(request):
    form=NewTicket(request.user)
    return render(request,'mmrapp/new_ticket.html',{'form':form})

admin.py

class UserExtend(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, blank=False,null=False,)
    client=models.ForeignKey('Client', on_delete=models.CASCADE,limit_choices_to={'is_active': True},)

    class Meta:
        verbose_name_plural='User Extends'

forms.py

from django import forms
from .models import Ticket 
from .admin import UserExtend

class NewTicket(forms.ModelForm):

    def __init__(self,user):
        self.business.queryset=business.objects.filter(client.id=userextend.client_id)

    class Meta:
        model=Ticket
        fields = ('subject','business')

new-ticket.html

{% extends 'mmrapp/__l_single_column.html' %}
{% load static %}

{% block main_col %}
    <h1>New Ticket</h1>
    <form method="POST" class="new-ticket">{% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="save btn btn-default">Submit</button>
    </form>
{% endblock main_col %}

Upvotes: 2

Views: 1725

Answers (1)

Ehsan Nouri
Ehsan Nouri

Reputation: 2040

You are doing it in the right way, just change the __init__ to this

class NewTicket(forms.ModelForm):

    def __init__(self,user, *args, **kwargs):
        super(NewTicket, self).__init__(*args, **kwargs)
        try:
            client_id = UserExtend.objects.values_list('client_id', flat=True).get(user=user)
            self.fields['business'].queryset=Business.objects.filter(client__id=client_id)
        except UserExtend.DoesNotExist:
            ### there is not userextend corresponding to this user, do what you want 
            pass


    class Meta:
        model=Ticket
        fields = ('subject','business')

also, don't forget to pass the request.user to the Form in your view.

Upvotes: 3

Related Questions