Django REST权限不返回403

时间:2017-02-27 16:38:03

标签: python django django-rest-framework

我现在正在为Django REST3.5创建一个测试用例 这是我的tests.py

问题
它返回201而不是403。我不希望创建对象

import os

import pytest
from rest_framework.test import APIClient

from apps.price_list_excel_files.models import PriceListExcelFile


def upload_excel(user: str, passwd: str) -> tuple:
    client = APIClient()
    client.login(username=user, password=passwd)

    dir_path = os.path.dirname(os.path.realpath(__file__))
    with open(dir_path + '/mixed_case.xlsx', 'rb') as fp:
        response = client.post(
            '/api/price-list-excel-files/',
            {'file': fp},
            format='multipart'
        )
    return client, response

def test_service_manager_upload_excel(prepare_service_mgrs):
    client, response = upload_excel("smgr1", "smgr1password")
    assert 403 == response.status_code
    assert 0 == PriceListExcelFile.objects.count()

models.py

from django.db import models
from django.db.models.signals import post_save

from apps.commons.models import AbstractModelController
from apps.price_list_excel_files.permissions import PriceListExcelFilePermisionMixin
from apps.price_list_excel_files.validators import validate_file_extension, validate_head_columns
from apps.price_lists.utils import get_xlsx2db


class PriceListExcelFile(AbstractModelController, PriceListExcelFilePermisionMixin):
    """
    A table that store the file record in the system
    Feature from Access Level. View is user be able to download an Excel file
                            Price list
    Service MGR             View
    Service Staff           View
    """
    file = models.FileField(upload_to='./excels', validators=[validate_file_extension, validate_head_columns])

    class Meta:
        ordering = ['-id']


post_save.connect(get_xlsx2db, sender=PriceListExcelFile)

permissions.py

from apps.accounting_users.models import AccountingUser
from apps.marketing_users.models import MarketingUser
from apps.mgmt_users.models import ManagementUser


class PriceListExcelFilePermisionMixin:
    @staticmethod
    def has_read_permission(request):
        return True

    def has_object_read_permission(self, request):
        return True

    @staticmethod
    def has_write_permission(request):
        import pdb;
        pdb.set_trace()
        if request.user.is_anonymous():
            return False
        else:
            return ManagementUser.objects.filter(user=request.user).exists() or \
                   AccountingUser.objects.filter(user=request.user).exists() or \
                   MarketingUser.objects.filter(user=request.user).exists()

views.py

from django.urls import reverse_lazy
from django.views.generic import CreateView
from rest_framework import generics

from apps.price_list_excel_files.forms import UploadFileForm
from apps.price_list_excel_files.models import PriceListExcelFile
from apps.price_list_excel_files.serializers import PriceListExcelFileSerializer


class PriceListExcelFileList(generics.ListCreateAPIView):
    queryset = PriceListExcelFile.objects.all()
    serializer_class = PriceListExcelFileSerializer


class PriceListExcelFileDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = PriceListExcelFile.objects.all()
    serializer_class = PriceListExcelFileSerializer


class PriceListUploadExcel(CreateView):
    template_name = 'price_list_excel_files/upload.html'
    form_class = UploadFileForm


    def get_form_kwargs(self):
        """
        This view has no PUT because user always upload new file
        :return:
        """
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

    def get_success_url(self):
        return reverse_lazy('api:price_list_excel_files:list')

我的调查

> /Users/el/.pyenv/versions/3.6.0/envs/siam-sbrand/lib/python3.6/site-packages/rest_framework/mixins.py(28)get_success_headers()
-> def get_success_headers(self, data):
(Pdb) list
 23             return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
 24
 25         def perform_create(self, serializer):
 26             serializer.save()
 27
 28  ->     def get_success_headers(self, data):
 29             try:
 30                 return {'Location': data[api_settings.URL_FIELD_NAME]}
 31             except (TypeError, KeyError):
 32                 return {}
 33
(Pdb) api_settings.URL_FIELD_NAME
'url'
(Pdb) data
{'id': 1, 'file': 'http://testserver/media/excels/mixed_case_bYU8C82.xlsx', 'permissions': {'write': False, 'read': True}}
(Pdb) data[api_settings.URL_FIELD_NAME]
*** KeyError: 'url'

Djano REST引发KeyError网址。然后我可以upload一个文件 这是一个错误还是我错过了我的测试用例?

1 个答案:

答案 0 :(得分:0)

@JensAStrup 你是对的!
我忘记了views.py的许可。非常感谢。
希望我的帖子可以作为一个例子

<强> views.py

from django.urls import reverse_lazy
from django.views.generic import CreateView
from dry_rest_permissions.generics import DRYPermissions
from rest_framework import generics

from apps.price_list_excel_files.forms import UploadFileForm
from apps.price_list_excel_files.models import PriceListExcelFile
from apps.price_list_excel_files.serializers import PriceListExcelFileSerializer


class PriceListExcelFileList(generics.ListCreateAPIView):
    permission_classes = (DRYPermissions,)
    queryset = PriceListExcelFile.objects.all()
    serializer_class = PriceListExcelFileSerializer


class PriceListExcelFileDetail(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = (DRYPermissions,)
    queryset = PriceListExcelFile.objects.all()
    serializer_class = PriceListExcelFileSerializer


class PriceListUploadExcel(CreateView):
    permission_classes = (DRYPermissions,)
    template_name = 'price_list_excel_files/upload.html'
    form_class = UploadFileForm

    def get_form_kwargs(self):
        """
        This view has no PUT because user always upload new file
        :return:
        """
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

    def get_success_url(self):
        return reverse_lazy('api:price_list_excel_files:list')

<强> tests.py

def test_service_manager_upload_excel(prepare_service_mgrs):
    client, response = upload_excel("smgr1", "smgr1password")
    assert 403 == response.status_code
    assert 0 == PriceListExcelFile.objects.count()