![](/img/trans.png)
[英]Django - How to get the object attribute before updating in Update class based view?
[英]How to update/change attribute in Django Class Based View Test
我創建了一個 mixin,它需要將一個屬性添加到基於 Class 的視圖 (cbv) 中,並且它按預期工作 - 但我很難專門“測試”該 mixin。
這是我的測試:
class TestView(GroupRequiredMixin, View):
group_required = ("test_group",)
raise_exception = True
def get(self, request):
return HttpResponse("OK")
class GroupRequiredMixinTest(TestCase):
def setUp(self):
group = GroupFactory(name="test_group")
self.user = UserFactory(groups=(group,))
def test_view_without_group_required_improperly_configured(self):
rfactory = RequestFactory()
request = rfactory.get("/fake-path")
request.user = self.user
view = TestView()
view.group_required = None
with self.assertRaises(ImproperlyConfigured):
view.as_view()(request)
此測試錯誤並顯示此消息: AttributeError: This method is available only on the class, not on instances.
測試這個的“適當”方法是什么?
我應該為我想測試的每種情況設置一個獨特的 class 嗎? 或者有沒有一種方法可以動態更改實例上的該屬性,例如我的測試失敗?
*編輯以添加 mixin(幾乎與核心 Django 版本的權限相同):
class GroupRequiredMixin(AccessMixin):
"""Verify that the current user has all specified groups."""
group_required = None
def handle_no_group(self):
if self.raise_exception or self.request.user.is_authenticated:
raise PermissionDenied(self.get_permission_denied_message())
path = self.request.build_absolute_uri()
resolved_login_url = resolve_url(self.get_login_url())
# If the login url is the same scheme and net location then use the
# path as the "next" url.
login_scheme, login_netloc = urlparse(resolved_login_url)[:2]
current_scheme, current_netloc = urlparse(path)[:2]
if (not login_scheme or login_scheme == current_scheme) and (
not login_netloc or login_netloc == current_netloc
):
path = self.request.get_full_path()
return redirect_to_login(
path,
resolved_login_url,
self.get_redirect_field_name(),
)
def get_group_required(self):
"""
Override this method to override the group_required attribute.
Must return an iterable.
"""
if self.group_required is None:
raise ImproperlyConfigured(
f"{self.__class__.__name__} is missing the "
f"group_required attribute. Define "
f"{self.__class__.__name__}.group_required, or override "
f"{self.__class__.__name__}.get_group_required()."
)
if isinstance(self.group_required, str):
groups = (self.group_required,)
else:
groups = self.group_required
return groups
def has_group(self):
"""
Override this method to customize the way groups are checked.
"""
groups = self.get_group_required()
if hasattr(self.request.user, "has_groups"):
return self.request.user.has_groups(groups)
else:
return self.handle_no_group()
def dispatch(self, request, *args, **kwargs):
if not self.has_group():
return self.handle_no_group()
return super().dispatch(request, *args, **kwargs)
with self.assertRaises(ImproperlyConfigured):
> view.as_view()(request)
my_app/tests/test_mixins.py:52:
_ _ _ _ _
def __get__(self, instance, cls=None):
if instance is not None:
> raise AttributeError("This method is available only on the class, not on instances.")
E AttributeError: This method is available only on the class, not on instances.
我能夠使它與以下內容一起工作:
rfactory = RequestFactory()
request = rfactory.get("/fake-path")
request.user = self.user
view = TestView.as_view(group_required=None)
with self.assertRaises(ImproperlyConfigured):
view(request)
我不能調用TestView()
來實例化一個新視圖——它需要是TestView.as_view()
來實例化它。 然后 arguments 在as_view()
部分中傳遞。
現在按預期工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.