django разрешения не соблюдаются - PullRequest
1 голос
/ 14 января 2020

Я пытаюсь показать кнопку, если вошедший в систему пользователь имеет необходимые разрешения.

Код в шаблоне:

  {% if perms.django_apo_training.can_add %}
   <a href="{% url 'training:trainee_add' %}">     
        <button type="button" class="btn btn-success">Add Trainee</button>    
   </a>
   {% endif %}

Я могу распечатать на веб-странице для отладки, что разрешения, которые пользователь имеет:

  <p> {{ perms.django_apo_training }} </p>

Показывает:

{'training.view_trainee', 'training.add_trainee', 'training.delete_trainee', 'training.change_trainee'}

, но

perms.django_apo_training.can_add 

всегда возвращает false, не уверен, что мне не хватает?

Даже дважды проверил в консоли администратора:

enter image description here

(если я предоставлю статус суперпользователя данному пользователю, то Если оператор работает и возвращает true?)

Вот модель для стажера

# Create your models here.
class Trainee(models.Model):
    objects = models.Manager()

    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length = 200)
    institution = models.CharField(max_length=200, blank=True)
    contact_phone = models.CharField(max_length=50, blank=True)
    contact_email = models.CharField(max_length=100, blank=True)
    trained_date = models.DateField('date trained')

    class Meta:
        ordering = ['institution']

    def __str__(self):
        return "Trainee: " + str(self.first_name) + " " + str(self.last_name) + "   " + str(self.institution)

Во-вторых ... даже если это работает, как я могу убедиться, что только те, кто с этим разрешение и вход в систему можно получить (это намного больше, чем требуется @login декоратор)

http://localhost:8000/training/add/

Наконец: я также создал модель для расширения пользовательской модели с использованием модели один-к-одному:

    user = models.OneToOneField(User, on_delete=models.CASCADE)

Внутри этой модели APOUser я ее называю, у меня есть другие поля, которые я бы полюбил , чтобы набрать кроме этих разрешений (в частности, что содержится в on_site_status), есть ли какой-то заданный способ или пример / рецепт того, как можно это сделать? (полная модель здесь)

class APOUser(models.Model):
    objects = models.Manager()

    user = models.OneToOneField(User, on_delete=models.CASCADE)

    institution =  models.ForeignKey("mainpage.Institution", on_delete=models.SET_NULL, null=True)
    on_site_status = models.ForeignKey("mainpage.SiteStatus", on_delete=models.SET_NULL,  null=True)
    refer_to_as = models.TextField(max_length = 30, blank=True, null=True) #if the above is custom
    room_preference  = models.ForeignKey("housing.Room", on_delete=models.SET_NULL,  null=True)

1 Ответ

2 голосов
/ 14 января 2020

Стандартные разрешения создаются в формате <app_label>.view_<model_name>. Таким образом, в приложении product со следующими моделями будет автоматически создано 8 разрешений.

class Category(models.Model):
    ...

class Product(models.Model):
    ...

# permissions for the Category model
'product.view_category'
'product.add_category'
'product.change_category'
'product.delete_category'

# permissions for the Product model
'product.view_product'
'product.add_product'
'product.change_product'
'product.delete_product'

В вашем примере perms.django_apo_training.can_add всегда будет возвращать False, поскольку нет разрешения can_add - если у вас нет модели с именем Add и вы не создали пользовательское разрешение. Правильный шаблон должен быть perms.training.add_training.

Также важно отметить, что проверка разрешений для суперпользователя всегда будет возвращать True, даже если разрешение не существует.

Для защищенных представлений с разрешениями и пользовательскими полями пользователя вы можете создать подкласс UserPassesTestMixin.

from django.contrib.auth.mixins import UserPassesTestMixin

def permissions_check(user):
    approved_profile_status = ['ADMIN', 'PURCHASER']
    permission = 'training.add_trainee'

    is_approved = user.profile.on_site_status in approved_profile_status
    has_perm = user.has_perm(permission)
    return is_approved or has_perm


class PermissionsMixin(UserPassesTestMixin):
    def test_func(self):
        return permissions_check(self.request.user)


class TraineeListView(PermissionsMixin, ListView):
    ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...