0

I am working on a Django Project, where one model (lets say Document) has the following field:

#In models.py

class Document (models.Model):
    choice = (('Yes','Yes'), ('No','No'))
    authorized = models.CharField (max_length=3, choices=choice, default='No')

Now, as a normal user creates a Document object, the authorized field is no. However, the superior needs to authorize the same before it is actually approved. Now, is there a permission system in django where one user can create an object but not authorize, whereas some other user - who has the permission - can authorize? If not, is the only way to do it is to create a custom field in user model and check it every time?

Sardorbek Imomaliev
  • 14,861
  • 2
  • 51
  • 63
Sayantan
  • 315
  • 5
  • 20

2 Answers2

0

Django has awesome auth system. I couldn't understand you scenario. But you could try something like this below By default every Model object comes with three Permission object like (add_document, change_document and delete_document in your case). If you want some custom permission you can add it in model Meta class like this:

You can add these permission to User object or Group object.

models.py

class Document (models.Model):
    ######
    class Meta:
        permissions = (("Can see document dashbaord", "see_document" ),)

and run python manage.py migrate to create new Permission object with codename as "see_document".

You can implement permissions in request handled by view like this:

view.py

from django.contrib.auth.mixins import PermissionRequiredMixin, permission_required

# For function based view
@pemission_required('document.see_document')
def someview(request):
    ######
    pass

# For class based views
class SomeView(PermissionRequiredMixin, BaseView):

    permission_required = 'document.see_document'

This could redirect any user with out the permssion to permission denied page. For more go through this https://docs.djangoproject.com/en/1.10/topics/auth/

Amar
  • 666
  • 5
  • 13
  • Thanks Amar for your time. Now you see, this is a complete model/object based permission. I want permission to be object state based. That is anyone can create an object. Once created, the workflow would move to her/his senior and the senior shall authorize it. In other words, I'm having a model (its purchaseInvoice & salesInvoice), which can be created by sub-ordinates. Once created, the model field Authorized is False. Seniors need to authorize it. How can this be done? – Sayantan Oct 07 '16 at 08:43
  • You can override default model save method – Amar Oct 08 '16 at 17:02
0

First of all, why you need to store possible values in CharField and not in BooleanField? I think you should consider changing to BooleanField.

You can do that by providing custom ModelAmin class in admin.py:

from django.contrib import admin
from .models import Document

@admin.register(Document)
class DocumentModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        if not request.user.is_superuser:
            self.exclude = ['authorized']
        return super(DocumentModelAdmin, self).get_form(request, obj, **kwargs)

So now on admin page of Document if it is not a superuser, user won't see authorized field. You can change that code for checking if it should be specific user, or has some permissions, or if user belongs to some Group and etc.

UPDATE

If you want it to be in general views, you can just pass different forms to users, depend on their roles|permissions|groups(i don't know how your so called senior is different from rest of the users). So the answer would be: create two forms, then pass on of them in template based on your request.user attributes.

vishes_shell
  • 22,409
  • 6
  • 71
  • 81
  • Yes, I should rather go with BooleanField, my bad. But the people are not superusers. And I dont want that to be used with admin but general views. Like say someone is creating an invoice (The actual model name is pursaeInvoice and salesInvoice). Once created a senior would authorize it. All these should happen in views and not through admin and certainly not through superusers. – Sayantan Oct 07 '16 at 08:39
  • @Vishes_shell...Thanks mate. But the issue I want to say is, like how can I prevent one person (who is not authorized to "authorize" the form) from accessing it. Look, I create object A and someone should authorize it. It's kind of like workflow. Now, should this accessibility be handled by checking is custom request.user.is_permitted_to_authorize field, or is there a better way? – Sayantan Oct 07 '16 at 08:51
  • @SayantanGanguly what you basically need to do, create some permission that you would assign superior users with, or create group that represent superior users, and in the view, depends on ` user.has_perm` or `group_name in user.groups` you would render one of two forms(one with authorized field and one without). And what happens there if you would enter the page as superior user, you would be seeing form that include `authorized` input, but if you aren't superior, you wouldn't even know that such field exists. – vishes_shell Oct 07 '16 at 09:07
  • Vishes_shell. This is what I wanted to know. Thanks a lot. Hope this could clear quite a few queries of other(s) in the Django community as well. – Sayantan Oct 07 '16 at 09:22