Проблема с настройкой условий из-за пользовательского декоратора сборки в Django

#python #django

#python #django

Вопрос:

Я пытаюсь создать пользовательский декоратор сборки в Django.

мой models.py :

 class myCustomeUser(AbstractUser):
    id = models.AutoField(primary_key=True)
    username = models.CharField(max_length=20, unique="True", blank=False)
    password = models.CharField(max_length=20, blank=False)
    is_Inspector = models.BooleanField(default=False)
    is_Industry = models.BooleanField(default=False)
    is_Admin = models.BooleanField(default=False)

    def __str__(self):
        return self.username

class Inspector(models.Model):
    user = models.ForeignKey(myCustomeUser, on_delete=models.CASCADE, related_name='inspector_releted_user')
    name = models.CharField(max_length=200, blank=False, null=True)
    gmail = models.EmailField(null=True, blank=False, unique=True)
    nid = models.IntegerField(blank=False, unique=True)
    inspector_varified = models.BooleanField(default=False, blank=True, null=True)

    def __str__(self):
        return self.name
 

Теперь я хочу создать декоратор, который позволит пользователю проходить, удовлетворяя следующим 3 условиям:

  1. user активен и вошел в систему
  2. is_Inspector значение равно True
  3. inspector_varified значение также True ( inspector_varified находится в Inspector классе under)

мой decorators.py :

 def inspector_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url='app2:request_login'):
    actual_decorator = user_passes_test(
        lambda u: u.is_active and u.is_Inspector,
        login_url=login_url,
        redirect_field_name=redirect_field_name
    )
    if function:
        return actual_decorator(function)
    return actual_decorator
 

Он поддерживает условия 1 и 2, но условие-3 им не удовлетворяется. Как я могу закодировать и для этого?

Комментарии:

1.Поскольку вы используете a ForeignKey , a User может иметь несколько связанных Inspector s, поэтому я не думаю, что это имеет большой смысл, скорее всего, вам следует использовать a OneToOneField .

2. Как я могу выполнить условие-3 , когда я использую OneToOneField ?

Ответ №1:

Само моделирование не имеет особого смысла: при использовании a ForeignKey a User может иметь несколько Inspector объектов, так что единого Inspector объекта не существует . Скорее всего, это не то, как вы хотите это смоделировать.

Вы можете преобразовать ForeignKey в OneToOneField [Django-doc], это, по сути, a ForeignKey с ограничением уникальности, так что это означает, что каждый Inspector из них будет ссылаться на другого пользователя.

 class Inspector(models.Model):
    user = models.OneToOneField(
        myCustomeUser,
        on_delete=models.CASCADE,
        related_name='inspector_releted_user'
    )
    # … 

затем мы можем проверить это с помощью:

 def check(user):
    try:
        return user.is_authenticated and user.is_Inspector and user.inspector_related_user.inspector_varified
    except AttributeError:
        return False 

затем мы можем проверить это с помощью:

 def inspector_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url='app2:request_login'):
    actual_decorator = user_passes_test(
        check,
        login_url=login_url,
        redirect_field_name=redirect_field_name
    )
    if function:
        return actual_decorator(function)
    return actual_decorator 

Тем не менее, моделирование выглядит не очень хорошо, тем более, что is_Inspector оно не обязательно должно быть полем модели пользователя: мы можем просто проверить, является ли a User инспектором, проверив, есть ли Inspector объект, который указывает на этого пользователя.

Кроме того, имена полей записываются в snake_case, так is_inspector что нет is_Inspector .