0

我是 Django 的新手。我一直在尝试使用自定义用户模型设置django-rules,但在尝试访问页面时不断收到 404。这是设置的外观:

自定义用户模型

class User(AbstractBaseUser, PermissionsMixin):

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)

    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)

    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )

    is_active = models.BooleanField(default=False)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.email

设置.py

AUTHENTICATION_BACKENDS = (
    'rules.permissions.ObjectPermissionBackend',
    'django.contrib.auth.backends.ModelBackend',
)

已安装的应用程序

INSTALLED_APPS = [
    # ...
    'rules.apps.AutodiscoverRulesConfig',
]

规则.py

@rules.predicate
def is_organisation_member(user, organisation):
    """Check if user is an active organisation member"""
    m = get_if_exists(
        OrganisationMember,
        user=user,
        organisation=organisation,
        organisation__state=Organisation.LifecycleState.ACTIVE
    )
    if not m:
        return False
    if not m.is_active:
        return False
    return True

rules.add_perm('organisations.member',  (is_authenticated & is_active & is_organisation_member))

视图.py

def get_organisation_by_slug(request, *args, **kwargs):
    return get_object_or_404(Organisation, workspace_name=kwargs['workspace'])

@permission_required('organisations.member', fn=get_organisation_by_slug)
def OrganisationView(request, workspace):
    # ...

网址.py

urlpatterns = [
    path('admin/', admin.site.urls),

    # ...

    # organisation
    path('<str:workspace>', v.OrganisationView, name="organisation-show"),
    # ...
]

根据调试,is_organisation_member返回True,但用户在尝试查看页面时仍然收到 404 错误(没有 django-rulespermission_required装饰器,页面可以正常工作)。任何想法为什么我会收到 404 响应?

4

1 回答 1

0

没有 django-rules 的permission_required装饰器,页面可以工作

那只说对了一半!当生成器被移除并且现有的测试数据存在时,它就起作用了。但是当查询什么也没返回时,出现了 404 错误。

我错误地认为问题在于设置规则,但删除装饰器后错误仍然存​​在。我之前没有看到这个错误,因为我总是自动生成测试数据(项目列表),但这次没有。因此,在查看视图函数后,我意识到当项目查询返回一个空列表时我引发了 404 错误:

@permission_required('organisations.member', fn=get_organisation_by_slug)
def OrganisationView(request, workspace):

    # Query strings:
    # Extract 'tab' value appended to url as
    # ?tab=projects
    tab = request.GET.get('tab', '')
    
    # Get organisation
    try:
        o = Organisation.objects.get(workspace_name=workspace)
    except Organisation.DoesNotExist:
        raise Http404("Not found.")

    if tab == 'projects':
        # Get project list 
        try:
            p = Project.objects.filter(organisation__workspace_name=workspace) \
                .order_by('-created_at')
        except Project.DoesNotExist:
            raise Http404("Not found")
    else:
        raise Http404("Not found...") # ERROR CAUSED BY THIS LINE
        # To fix the error, I have removed the above line and added the below query
        # p = Project.objects.filter(organisation__workspace_name=workspace) \
        #     .order_by('-created_at')

    # Set context 
    context = {
        'o': o,
        'projects': p
    }

    return render(request, 'bb/home.html', context)

因为我确信我的观点是好的,所以我没有发布完整的功能,这使得其他人很难发现错误。添加到 User 模型后,我意识到错误出现在视图中,has_perm(self, perm, obj=None): return True但仍然出现 404 错误。

于 2020-09-10T07:34:18.330 回答