如何解决“权限匹配查询不存在”。在Django

时间:2019-04-18 02:49:30

标签: python django pytest django-guardian

我正在为Django中的一所学校创建一个网络系统,为此,我决定将Django-Gurdian用于基于对象的权限,并且在迁移后设置一个信号来创建默认组,例如:all-students ,所有教师等...我正在使用Pytest进行测试,但是由于某种原因,当我运行它们时,所有权限接缝都消失了。

这是我做的第一个如此规模的项目,我正在创建它以学习更多知识。这也是我在这个网站上的第一个问题。抱歉,很多注释和变量等是葡萄牙语,或者与英语混在一起。如果您需要,我可以提供翻译。而且我知道大多数代码编写得很差,正如我说的我还在学习。

我已经尝试了普通服务器,但是没有接缝错误。当我从终端迁移时,一切正常。我正在Windows 10中运行它,使用PyCharm来运行它。    我正在使用Python 3.7,Django 2.1.8,django-guardian 1.5.0,pytest 4.2.0。

apps.py-注册信号

class EscolaConfig(AppConfig):
     name = 'escola'

     def ready(self):
         from django.db.models.signals import post_migrate
         from .signals import populate_models
         post_migrate.connect(populate_models, sender=self)

signals.py-创建组

INITIAL_GROUPS = {
    'Admin': [
              'escola.add_turma',
              'escola.add_aluno',
              'escola.can_add_aluno',
              'escola.mudar_horario',
              'escola.can_populate_turma',
              ],
    'Todos_Alunos': [],
}
def populate_models(sender, **kwargs):
    from django.apps import apps
    from django.contrib.auth.management import create_permissions

    for app_config in apps.get_app_configs():
        app_config.models_module = True
        create_permissions(app_config, verbosity=0)
        app_config.models_module = None

    from django.contrib.auth.models import Group, Permission
    from escola.permission_utils import permission_names_to_objects

    logger.info("Iniciando modulo, para adição de Itens pós migrate.")
    logger.info("Iniciando verificação de grupos:")
    for g in INITIAL_GROUPS.keys():
        group, created = Group.objects.get_or_create(name=g)
        if created:
            logger.info(f"Criado grupo {g}.")
        else:
            logger.info(f"Grupo {g} já existe.")

        logger.info(f"Iniciando metodo de dar Permissões para o grupo {g}")
        logger.debug(f"Permissões a serem dadas:{INITIAL_GROUPS[g]}")
        perms_to_add = permission_names_to_objects(INITIAL_GROUPS[g])
        logger.info(f"Dando permissões {perms_to_add.__str__()} para o grupo {g}")
        group.permissions.add(*perms_to_add)

permission_utils.py-通过名称获取权限对象

def permission_names_to_objects(names):
    """
    Given an iterable of permission names (e.g. 'app_label.add_model'),
    return an iterable of Permission objects for them.  The permission
    must already exist, because a permission name is not enough information
    to create a new permission.
    """
    result = []
    for name in names:
        name: str
        app_label, codename = name.split(".", 1)
        # Is that enough to be unique? Hope so
        try:
            result.append(Permission.objects.get(content_type__app_label=app_label,
                                                 codename=codename))
        except Permission.DoesNotExist:
            logger.error("NO SUCH PERMISSION: %s, %s" % (app_label, codename))
    return result

models.py

[...]
class Turma(models.Model, ExportModelOperationsMixin('Turma')):
    """ Uma turma, conjunto de alunos, materias, tarefas, tambem possui um horario"""
    numero = models.IntegerField()
    ano = models.IntegerField()
    lider = models.ForeignKey(Group, on_delete=models.DO_NOTHING, null=True, blank=True, related_name='turma_lider')
    vicelider = models.ForeignKey(Group, on_delete=models.DO_NOTHING, null=True, blank=True, related_name='turma_vicelider')
    regente = models.ForeignKey(Group, on_delete=models.DO_NOTHING, null=True, blank=True, related_name='turma_regente')

    class Meta:
        """Meta das Models"""
        permissions = (
            ('can_populate_turma', "Pode popular turmas"                ),
            ('can_add_aluno'     , "Pode adicionar um aluno a turma."   ),
            ('mudar_horario'     , "Pode editar o horario."             ),
            ('can_add_materia'   , 'Pode adicionar uma materia a turma.'),
            ('can_add_tarefa'    , "Pode adicionar uma tarefa."         ),
        )

    def get_or_create_lider_group(self):
        """Retorna o grupo de lider, que deve possuir apenas um usuario."""
        if not self.lider:
            logging.info(Group.objects.filter(name=f'lider_turma_{self.pk}'))
            logging.info(len(Group.objects.filter(name=f'lider_turma_{self.pk}')))
            if not len(Group.objects.filter(name=f'lider_turma_{self.pk}')) == 0:
                self.lider = Group.objects.get(name=f'lider_turma_{self.pk}')
            else:
                self.lider = Group.objects.create(name=f'lider_turma_{self.pk}')
        assign_perm('escola.mudar_horario', self.lider, obj=self)
        assign_perm('escola.can_add_materia', self.lider, obj=self)
        assign_perm('escola.can_add_tarefa', self.lider, obj=self)
        return self.lider

    def get_or_create_vicelider_group(self):
        """Retorna o grupo de vicelider, que deve ter apenas um usuario."""
        if not self.vicelider:
            logging.info(Group.objects.filter(name=f'vicelider_turma_{self.pk}'))
            logging.info(len(Group.objects.filter(name=f'vicelider_turma_{self.pk}')))
            if len(Group.objects.filter(name=f'vicelider_turma_{self.pk}').all()) != 0:
                self.vicelider = Group.objects.get(name=f'vicelider_turma_{self.pk}')
            else:
                self.vicelider = Group.objects.create(name=f'vicelider_turma_{self.pk}')
        assign_perm('escola.mudar_horario', self.vicelider, obj=self)
        assign_perm('escola.can_add_materia', self.vicelider, obj=self)
        assign_perm('escola.can_add_tarefa', self.vicelider, obj=self)
        return self.vicelider

    def get_or_create_regente_group(self):
        """ Retorna o grupo de regente, que deve ter apenas um usuario. """
        if not self.regente:
            logging.info(f"Grupos regente da turma:{Group.objects.filter(name=f'regente_turma_{self.pk}')}")
            logging.info(f"QNT:{len(Group.objects.filter(name=f'regente_turma_{self.pk}'))}")
            if len(Group.objects.filter(name=f'regente_turma_{self.pk}')) > 0:
                self.regente = Group.objects.get(name=f'regente_turma_{self.pk}')
            else:
                self.regente = Group.objects.create(name=f'regente_turma_{self.pk}')
        logging.info(permission_names_to_objects(['escola.can_add_aluno',
                                                  'escola.mudar_horario',
                                                  'escola.can_add_materia',
                                                  'escola.can_add_tarefa']))
        assign_perm('escola.can_add_aluno', self.regente, obj=self)
        assign_perm('escola.mudar_horario', self.regente, obj=self)
        assign_perm('escola.can_add_materia', self.regente, obj=self)
        assign_perm('escola.can_add_tarefa', self.regente, obj=self)
        return self.regente

[...]

我上面提到的错误发生在上面的assign_perm()中。

tests / test_views.py-引发错误的测试之一

    def test_create_with_valid(self):
        c = Client()
        admin = create_admin()
        c.force_login(admin)
        profe = create_professor()
        turma__pk = create_turma().pk
        response = c.post(reverse('escola:add-cargo', args=[turma__pk, ]),
                          {'nome': 'Regencia', 'ocupante': profe.user.pk.__str__(),
                           'cod_especial': '5', 'ativo': 'True'})
        self.assertRedirects(response, reverse('escola:list-cargos', args=[turma__pk, ]))

        cargo_criado: CargoTurma = CargoTurma.objects.get(nome='Regencia')
        assert cargo_criado.turma is not None
        assert cargo_criado.nome == 'Regencia'
        assert cargo_criado.ativo is True
        assert cargo_criado.cod_especial == 5
        assert cargo_criado.ocupante == profe.user

tests / helpers / utils.py-测试实用程序。



def create_admin():
    user = mixer.blend(User, is_superuser=True)
    return user


def create_aluno(turma=None, user=None):
    if not turma:
        turma = mixer.blend(Turma)
    if user is None:
        user = mixer.blend(User)
    profile = mixer.blend(Profile, user=user, is_aluno=True, is_professor=False)
    aluno = mixer.blend(Aluno, user=user)
    return aluno


def create_professor():
    user = mixer.blend(User)
    profile = mixer.blend(Profile, user=user, is_aluno=False, is_professor=True)
    professor = mixer.blend(Professor, user=user)
    return professor


def create_turma():
    turma = mixer.blend(Turma, ano=datetime.today().year)
    horario = mixer.blend(Horario, turma=turma)
    aluno = create_aluno(turma=turma)
    prof = create_professor()
    materia = mixer.blend(MateriaDaTurma, professor=prof, turma=turma)
    return turma

最后,在我创建此文件后,破解它的代码第一次出现了错误: user_utils.py-创建特定用户类型时,我的应用程序的实用程序


def create_user(username, password, **kwargs) -> User:
    """
    Cria um usuario com esses dados
    :param username: Nome de usuario
    :param password: Senha
    :param kwargs: Veja abaixo...
    :keyword email:
        Opicional email do usuario
    :return: Usuario Criado
    :rtype User
    """
    u = User.objects.create_user(username, password=password, email=kwargs.get('email'))
    p = Profile(user=u)
    p.is_professor = False
    p.is_aluno = False
    p.save()
    return u


def give_admin(user: User) -> None:
    """
    Transforma o usuario em admin;
    :param User user:
    :return: None
    """
    user.is_staff = True
    user.groups.add(get_admin_group())
    user.save()


def create_admin_user(username: str, password: str, *args, **kwargs) -> User:
    """
    Cria um usuario com status de admin.
    :param username: Nome de usuario para ele
    :param password: Senha
    :keyword email:
        Opicional, email da conta a ser criada
    :return: Usuario criado
    :rtype: User
    """
    user = User.objects.create_user(username, password=password, email=kwargs.get('email'))
    give_admin(user)
    return user


def get_admin_group() -> Group:
    """
    Pega ou cria o grupo de Admins
    :return: Grupo de Admins
    :rtype: Group
    LOGS:"Por algum motivo o Grupo admin não havia sido criado." se um Grupo ainda não tiver sido criado,
    o que não deveria acontecer, já que esse grupo é criado após os migrates.
    """
    g, c = Group.objects.get_or_create(name="Admin")
    if c:
        logger.warning("Por algum motivo o Grupo admin não havia sido criado.")
    return g


def create_aluno_user(username, senha, turma: Turma, nome, *args, **kwargs):
    """
    Cria um usuario como aluno
    :param username: Nome de usuario
    :param senha: senha
    :param turma: Turma do aluno
    :param nome: Nome completo do aluno
    :keyword n_chamda: Numero da chmada do aluno.
    :return:
    """
    u = create_user(username, senha)
    p = u.profile_escola
    p.is_aluno = True
    p.save()
    a = Aluno()
    a.user = u
    a.turma = turma
    a.nome = nome
    if kwargs.get('n_chamda'):
        a.chamada = kwargs.get('n_chamda')
    a.save()
    u.groups.add(get_all_alunos_group())
    u.groups.add(get_turma_alunos_group(turma.pk))
    return u


def get_all_alunos_group():
    g, created = Group.objects.get_or_create(name='Todos_Alunos')
    return g


def get_turma_alunos_group(turma_pk):
    g, created = Group.objects.get_or_create(name=f'Alunos_{turma_pk}')
    return g


def create_professor_user(username, password, name):
    u = create_user(username, password)
    p = u.profile_escola
    p.is_professor = True
    u.groups.add(get_all_professor_group())
    P = Professor()
    P.user = u
    P.nome = name
    return u


def get_all_professor_group():
    g, created = Group.objects.get_or_create(name='Todos_Professor')
    return g

我原本希望这些功能能够吸引一群Turma的学生,但是当我运行测试时,该模型的所有权限都消失了 如果您需要更多信息,请不要害怕,或者在GitHub存储库中寻求它们:https://github.com/vini84200/medusa2/tree/a72752252d57f9e2fdf12851e88e6d82390f38e4 或在测试日志中:https://travis-ci.org/vini84200/medusa2/jobs/521532783 谢谢。

0 个答案:

没有答案