Saturday 29 August 2015

Django Choice form filtered base on logged username


With Django we have form which have many feature to faster development. I usually use Django Model Form, which get the meta data from a model and spit out a form ready to use and rendered to client in HTML form.

Django Select Form
Now i need to get a choice field in django , but the choice field get from a foreign key, and need to filter it base on the username logged in to system.

So the purpose is to get a list of choice which only available for the specific user, let say the user belong to VIP user group. So user only see the choice only available to VIP user group defined before by admin.


So lets get the how to do it. Here are the model code :
  class Usergroup(models.Model):
    """Models for User Group"""
    group_name = models.CharField(max_length=64, null = False, default = '')
    owner = models.CharField(max_length=64, null = False, default = ''  )
    update_by = models.CharField(max_length=250,null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
            db_table = 'Usergroup'
            ordering = ['-created_at']
            verbose_name_plural = 'usergroup'
            permissions = (
                ("view_usergroup", "Can see detail of the User Group"),
                ("list_usergroup", "Can list all the User Group"),
            )

    def __unicode__(self):
        return self.group_name

    @models.permalink
    def get_absolute_url(self):
        return ('user_group', (),{'group_name':self.group_name})




here are the form code :
   class AdminVIPUsersModelForm(forms.ModelForm):
     """For new and edit model"""
     def __init__(self, *args, **kwargs):
        super(AdminVIPUsersModelForm, self).__init__(*args, **kwargs)
        for name, field in self.fields.items():
            if field.widget.__class__ == forms.widgets.TextInput:
                if field.widget.attrs.has_key('class'):
                    field.widget.attrs['class'] += ' form-control input-medium'
                else:
                    field.widget.attrs.update({'class':'form-control input-medium'})

     class Meta:
         model = VIPuser
         fields = ('user_name','passwd','user_group','access_type','owner')
     user_name = forms.CharField(widget=forms.TextInput(attrs={ \
                    'class':'form-control input-medium'}),label='User Name' \
                    ,help_text="Used for login on Wifi")
     passwd = forms.CharField(widget=forms.PasswordInput(attrs={ \
                    'class':'form-control input-medium'}),label='Password' \
                    ,help_text="Passoword for user login from HotSpot")
     user_group = forms.ModelChoiceField(widget=forms.Select(attrs={ \
                    'class':'form-control input-medium'}),label='Group' \
                    ,help_text="Group the user belong", \
                    queryset = Groupchoices.objects.all())
     access_type = forms.CharField(widget=forms.TextInput(attrs={ \
                    'class':'form-control input-medium'}),label='Access Type' \
                    ,help_text="User access type description")
     owner = forms.CharField(widget=forms.TextInput(attrs={ \
                    'class':'form-control input-small'}),label='Owner' \
                    ,help_text="The creator of the group and will used only \
                    by the creator")

And in the views.py :
        form = AdminVIPUsersModelForm()
        form.fields["user_group"].queryset = Usergroup.objects.filter(owner=request.user.username)


This usecase will be used when there is foreign key relation on each table.

Hope this help someone as i documented for my future reference in this blog.

0 comments:

Post a Comment

Twitter Delicious Facebook Digg Stumbleupon Favorites More