์ฐ์ , ์ฒ์๋ถํฐ ์ญํ ์ ์ถ๊ฐํ์ง ์์ ์ด์ ๋ฅผ ์ค๋ช ํ๊ฒ ์ต๋๋ค. ๊ฐ๋จํ ๋งํด์ Django์ ์ ์ฑ ์ ๊ฐ๋จํ์ง๋ง ์ ๋ง๋ค์ด์ง ๋ฐฐํฐ๋ฆฌ๋ฅผ ํฌํจํ๋ ๊ฒ์ ๋๋ค. django.contrib.auth๊ฐ ๊ฐ์ฅ ์ข์ ์์ ๋๋ค. ์ฌ๋๋ค์ด ์์ฒด ๊ตฌํ์ผ๋ก ์ธ์ฆ์ ๋ช ๋ฒ์ด๋ ๊ตํํด์ผ ํฉ๋๊น? ๋๋ ๊ทธ๋ ๊ฒ ๋ง์ง ์๋ค๊ณ ๋ฏฟ์ต๋๋ค. ๊ฐ๋์ธ์ ์ ์ ์ ์ด๊ณ ๊ฐ๋จํ ์ธํฐํ์ด์ค๋ก ์ธ์ฆ ์ฑ์ ๋ํ ์ผ์ข ์ "ํ์ฅ"์ ์ํ ๊ฒ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ ๋ค์ผ. ์ถ๊ฐ ๊ธฐ๋ฅ์ด ๋ง์ด ํฌํจ๋์ด ์์ง ์์ต๋๋ค(์ผ๋ถ ๋ฐ๋ก ๊ฐ๊ธฐ ๊ธฐ๋ฅ ์ ์ธ - "์ ์" ๋ถ๋ถ ์ฐธ์กฐ).
์ด์ ์ญํ ์ ์ด๋ป์ต๋๊น? ํญ์ ํ์ํ ๋ชจ๋ ๊ฒ? ์ฌ์ค, ๋๋ ๊ทธ๋ ์ง ์๋ค๊ณ ๋ฏฟ๋๋ค. ๊ทธ๋ฃน๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค. ์ฌ์ฉ์๋ ๋๋ถ๋ถ์ ๋ชจ๋ ์์ฉ ํ๋ก๊ทธ๋จ์ ๋ํ ๊ธฐ๋ณธ ์ํฐํฐ์ด๋ฏ๋ก ํ์ํฉ๋๋ค.
์, ์ด์ ๊ฑฐ์ v1.0์ด ๋์์ต๋๋ค. ๋ฐ๋ผ์ v1.1์ ๊ฒฝ์ฐ ์ญํ ์ง์์ด ๊ฐ์ฅ ์ค์ํ ๊ธฐ๋ฅ์ผ ๊ฒ์ ๋๋ค. ๊ทธ๋๋ ์ ์๊ฐ์๋ ์ด๋ค ์์ผ๋ก๋ "์ ํ์ "์ด์ด์ผ ํฉ๋๋ค.
+1 ํ์ง๋ง ์ญํ ์ django๋ก ์์ฑ๋ ๋๋ถ๋ถ์ ์ฑ์์ ๊ฑฐ์ ํ์ํ์ง ์์ ๊ฒ์
๋๋ค.
๊ฐ๋ ์ฐ๋ฆฌ ๊ฐ์ ์ฌ๋์ด django๊ฐ ์ค์ ๋ก ๋ง๋ค์ด์ง์ง ์์ ์ฑ(์ฌ์ฉ์ ์ง์ ๋ฌธ์ ๊ด๋ฆฌ ์์คํ
)์ ๊ตฌํํ๋ ค๊ณ ํ๊ณ , ํ๋ง๊ฐ ๋ง์ ๋ ์ญํ ์ ๋ํด ์๊ฐํ๊ธฐ ์์ํฉ๋๋ค. ์ญํ ๊ณผ ์์ v1.1๋ก ๋ง๋ค์ด์ผ ํ๋ ๋ ๊ฐ์ง
์ต์ ๋ถ๋ถ์ ์ฝ์ต๋๋ค. django๋ฅผ ์ฌ์ฉํ๋ค๊ณ ๊ทธ๋ฃน์ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ฒ๋ผ ์ฌ๋๋ค์ด ์ญํ ์ ์ ์ํ๋๋ก ๋ง๋ค์ง ๋ง์ญ์์ค.
thx ์ฑ์ฉ btw.
๊ธ์ฐ ๊ฑด๊ฐ ์ฆ์ง ํํ
๊ตฌํ์ ๋ฐ๋ผ ์ญํ ์ ๋ํด +1.
์ญํ ๋ฐ ์์์ ๋ํด +1
๋๋ ์ญํ ์ ๋ํด "๊ถํ ๊ทธ๋ฃน"์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ด๊ฒ์ด ๋น์ ์๊ฒ๋ ๋์ผํ์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ด ์ญํ ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๋ง์ ๊ถํ์ ๋ ์ฝ๊ฒ ํ ๋นํ ์ ์์ต๋๋ค. ํ ์ญํ ์ ๋ค๋ฅธ ์ญํ ๋ก ๋นผ๊ฑฐ๋ ๊ต์ฐจ์ ๋ฑ์ ์ป๊ธฐ ์ํด Python ์ธํธ๋ฅผ ์ฌ์ฉํ์ฌ ์ด๊ฒ์ ๊ตฌํํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
http://docs.python.org/library/stdtypes.html#set -types-set-frozenset
http://en.wikibooks.org/wiki/Python_Programming/Sets
์ญํ , ์์ ๋ฐ ์ ํ ์ฌํญ์ ๋ํด +1
์๋
ํ์ธ์ ์ฌ๋ฌ๋ถ,
์ ๋ ์ญํ ๊ธฐ๋ฐ ๊ฐ์ฒด ๊ถํ์ด ํ์ํ๊ฑฐ๋ ๊ฐ๊ณ ์ถ์ ์ฌ๋ ์ค ํ ๋ช
์
๋๋ค.
๋๋ ์ด ํ ๋ก ์์ ์์ฃผ ์ข์ ์ด์ ๋ก django-guardian์ ์ฐ์ ์์๊ฐ ์๋์ ์ดํดํฉ๋๋ค. ๊ทธ๋์ ๋๋ ๋๋ง์ ์ฑ์ ๋ง๋ค ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ django-guardian์ ๋๋ถ๋ถ์ ๊ธฐ๋ฅ๊ณผ ๊ตฌ์ฑ ์์๋ ๊ด์ฐฎ๋ค๊ณ ์๊ฐํ๋ฉฐ ๊ฐ๋ฅํ๋ฉด ๋ฐํด๋ฅผ ๋ค์ ๋ฐ๋ช ํ์ง ์๊ณ ์ฌ์ฌ์ฉํ๊ณ ์ถ์ต๋๋ค. ๊ทธ๋์ ์ ์ง๋ฌธ์ django-guarding์ ์กฐ๊ธ ๋ ์ฐ๊ฒฐ ๊ฐ๋ฅํ๊ฒ ๋ง๋ค ์ํฅ์ด ์๋์ง์ ๋๋ค. ์๋ฅผ ๋ค์ด(์ฝ๋๋ฅผ ์งํํ๋ ๋์ ๋ด ๋ง์์ ๊ฐ์ฅ ๋จผ์ ๋ ์ค๋ฅธ ๊ฒ): ObjectPermissionChecker์ ๋ํ ์ค์ ์ ์ง์ ํ๋ฉด ๋ค๋ฅธ ์ฑ์ด Checker ํด๋์ค๋ฅผ ์ญํ ์ ์ฒ๋ฆฌํ๋ ๊ฒ์ผ๋ก ๋์ฒดํ ์ ์์ต๋๊น?
์ฌ๋ฌ๋ถ์ ์ด๋ป๊ฒ ์๊ฐํ์ธ์?
๊ฐ์ฌ ํด์
์๋ฅด๊ฒ
Hej @schacki , ๊ทธ๊ฒ์ ์ค์ ๋ก ๊ฝค ์ข์ ์๊ฐ์ ๋๋ค. ํ ์คํธ๋ ๊ธฐ๋ณธ์ด ์๋ ๊ฒ์ฌ๊ธฐ ํด๋์ค์ ๋ํด ์คํจํ ๊ฐ๋ฅ์ฑ์ด ๋์ง๋ง ์ด๋ฅผ ํ์ํ๊ฑฐ๋ ๊ธฐ๋ณธ ๊ฒ์ฌ๊ธฐ๋ก๋ง ์คํ๋๋๋ก ํ ์ ์์ต๋๋ค. ํน์ ์์ ์ ์์ฑํ ์ ์์ต๋๊น?
๋๋ ๊ธฐ๋ณธ์ด ์๋ ๊ฒ์ฌ๊ธฐ ํด๋์ค๋ฅผ django-guardign์ ์ผ๋ถ๊ฐ ์๋๋ผ "๊ธฐํ" ์ฑ์ ์ผ๋ถ๋ก ๋ง๋ค ๊ฒ์ด๋ฏ๋ก ๊ธฐ๋ณธ์ด ์๋ ๊ฒ์ฌ๊ธฐ ํด๋์ค์ ๋ํ ๋ค๋ฅธ ์ฑ์ ์์ ์ ๋๋ค. ์์ ์ ์์ํ๊ธฐ ์ ์ ์กฐ์ ๋ฐ ๋ณ๊ฒฝํด์ผ ํ ์ฌํญ์ ๋ํ ๋ณด๋ค ์ฒ ์ ํ ๋ถ์์ ์ํํ๊ฒ ์ต๋๋ค. "์์ "์ ์ฌ์ฉํ๋ฉด ๋ณ๋์ ๋ฌธ์ ๋ฅผ ์๋ฏธํ๋ค๊ณ ๊ฐ์ ํฉ๋๊น? btw: ์ด ์์ ์ด ์งํ๋๊ธฐ๊น์ง ๋ช ์ฃผ๊ฐ ๊ฑธ๋ฆด ์ ์์ต๋๋ค.
this[1] ํ๋ก์ ํธ์ ๋์์ด ๋์ จ๋์?
[1] https://github.com/vintasoftware/django-role-permissions
#330์์ @suriya ๊ฐ ๋ค์ ํ ์คํธ๋ฅผ ๋ณต์ฌํ์ต๋๋ค.
์ง๋ #23์์ django-guardian์ ์ญํ ์ง์์ ์ถ๊ฐํ๋ ๊ฒ์ ๋ํ ๋ ผ์๊ฐ ์์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ฉ๋ฆฌ ์์ง์ด์ง ์์์ต๋๋ค. ์ด๊ฒ์ ์๋ง๋ django-guardian์ ์ญํ ์ ์ถ๊ฐํ๋ ๊ฒ์ด ๋งค์ฐ ๋ณต์กํ ์์ ์ฒ๋ผ ๋ณด์ด๊ธฐ ๋๋ฌธ์ผ ๊ฒ์ ๋๋ค.
์์ฃผ ๊ฐ๋จํ ์ ์์ด ์๋ ๊ฒ ๊ฐ์์. ๋ด์ธ์ฐ๊ณ ๊ด์ฌ์ด ์๋ค๋ฉด ์ํํ๊ณ ์ถ์ต๋๋ค. ํ์ฌ, ๋๋ ์ด ๊ธฐ๋ฅ์ด ์๋ django-guardian์ ๋ด ์์ ์ ํฌํฌ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๋ค๋ฅธ ์ฌ๋๋ค๋ ์ด๊ฒ์ ์ฌ์ฉํ๋ ๊ฒ์ ๋ณด๋ ๊ฒ์ด ์ข์ต๋๋ค.
๋ทฐ์ ๋ํ django-guardian์ ๊ถํ ๊ฒ์ฌ์ ํต์ฌ์ get_403_or_None()
ํจ์์์ ๊ตฌํ๋ฉ๋๋ค. ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉ์์๊ฒ ํ์ํ ๋ชจ๋ ๊ถํ์ด ์๋์ง ํ์ธํฉ๋๋ค. https://github.com/lukaszb/django-guardian/blob/112c373f213a19d93baa81fa4a941a41333115b5/guardian/utils.py#L98
has_permissions = all(request.user.has_perm(perm, obj) for perm in perms)
์ง์ ์ญํ ์ ์ฌ์ํ ๋ณ๊ฒฝ์
๋๋ค. ์ฌ์ฉ์์๊ฒ all
๊ถํ์ด ์๋์ง ํ์ธํ๋ ๋์ ์ฌ์ฉ์๊ฐ ํ๋ ์ด์์ ๊ถํ์ ์ถฉ์กฑํ๋์ง ํ์ธํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ๊ฐ์ ๊ฒ
if require_all_permissions:
has_permissions = all(request.user.has_perm(perm, obj) for perm in perms)
else:
has_permissions = any(request.user.has_perm(perm, obj) for perm in perms)
๊ทธ๊ฒ์ํด์ผํฉ๋๋ค. ์ด ์ง์์ ์ถ๊ฐํ๋ ค๋ฉด get_403_or_None()
์ ์ ํ๋๊ทธ๋ฅผ ์ ์ํ๊ณ ๋ชจ๋ ๊ถํ์ ์ถฉ์กฑํ ์ง ์๋๋ฉด ์ผ๋ถ ๊ถํ๋ง ์ถฉ์กฑํ ์ง ์ง์ ํ๋ ํธ์ถ์๋ฅผ ์ ์ํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
๋๋ #386์ ์ด์๊ณ ์ด๊ฒ์ด ์๋ง ๊ฐ๋ค๋ ๊ฒ์ ๊นจ๋ซ๊ณ ์๋ค. ๋ด๊ฐ ํ์ํ ๊ฒ์ ๊ถํ์ ํ์ธํ๋ ์ฝ๋์์ "์ด ์ฌ์ฉ์์๊ฒ ์ด ๊ฐ์ฒด์ ๋ํ ํธ์ง ๊ถํ์ด ์์ต๋๊น?"๋ผ๊ณ ํ ์ ์์ง๋ง ์ฌ์ฉ์์๊ฒ ๊ถํ์ ํ ๋นํ ๋ "์กฐ์ ์" ๊ถํ์ ํ ๋นํ๋ ๊ฒ์ ๋๋ค. "ํธ์ง" ๊ถํ์ ํฌํจํ ์ฌ๋ฌ ๊ถํ์ ์์ ์งํฉ์ ๋๋ค. ์ด๋ฅผ ํตํด ๋์ค์ ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ์๋์ผ๋ก ๊ถํ์ ํ ๋นํ์ง ์๊ณ ๋ "์กฐ์ ์"์๊ฒ ๋ ๋ง์ ๊ถํ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
์ด ๊ถํ ๊ณ์ธต์ ์ด๋ฆ์ ์ญํ ๋ก ์ง์ ํ ์ ์์ต๋๋ค.
์ญํ , ์์ ๋ฐ ์ ํ ์ฌํญ์ ๋ํด +1
๋ค์๊ณผ ๊ฐ์ ์ญํ ๊ฐ๋ ์ ๊ตฌํํ์ต๋๋ค.
get_40x_or_None
์ฌ์ฉ์ ์ ์from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.http import HttpResponseForbidden, HttpResponseNotFound
from django.shortcuts import render
from guardian.conf import settings as guardian_settings
def get_40x_or_None(request, perms, global_perms, obj=None, login_url=None,
redirect_field_name=None, return_403=False,
return_404=False):
"""check if the given perms and global_perms are both granted by the user in combination"""
login_url = login_url or settings.LOGIN_URL
redirect_field_name = redirect_field_name or REDIRECT_FIELD_NAME
# Handles both original and with object provided permission check
# as ``obj`` defaults to None
has_permissions = False
if not has_permissions:
has_permissions = all(request.user.has_perm(perm, obj) for perm in perms) and \
all(request.user.has_perm(perm) for perm in global_perms)
if not has_permissions:
if return_403:
if guardian_settings.RENDER_403:
response = render(request, guardian_settings.TEMPLATE_403)
response.status_code = 403
return response
elif guardian_settings.RAISE_403:
raise PermissionDenied
return HttpResponseForbidden()
if return_404:
if guardian_settings.RENDER_404:
response = render(request, guardian_settings.TEMPLATE_404)
response.status_code = 404
return response
elif guardian_settings.RAISE_404:
raise ObjectDoesNotExist
return HttpResponseNotFound()
else:
from django.contrib.auth.views import redirect_to_login
return redirect_to_login(request.get_full_path(),
login_url,
redirect_field_name)
GlobalPermissionRequiredMixin
๊ตฌํfrom django.core.exceptions import PermissionDenied, ImproperlyConfigured
from guardian.mixins import PermissionRequiredMixin
from collections.abc import Iterable
from permission.utils import get_40x_or_None
class GlobalPermissionRequiredMixin(PermissionRequiredMixin):
global_permission_required = None
def get_global_required_permissions(self, request=None):
"""
Returns list of permissions in format *<app_label>.<codename>* that
should be checked against *request.user* and *object*. By default, it
returns list from ``global_permission_required`` attribute.
:param request: Original request.
"""
if isinstance(self.global_permission_required, str):
perms = [self.global_permission_required]
elif isinstance(self.global_permission_required, Iterable):
perms = [p for p in self.global_permission_required]
else:
raise ImproperlyConfigured("'GlobalPermissionRequiredMixin' requires "
"'global_permission_required' attribute to be set to "
"'<app_label>.<permission codename>' but is set to '%s' instead"
% self.global_permission_required)
return perms
def check_permissions(self, request):
"""
Checks if *request.user* has all permissions returned by
*get_required_permissions* method.
:param request: Original request.
"""
obj = self.get_permission_object()
forbidden = get_40x_or_None(request,
perms=self.get_required_permissions(request),
global_perms=self.get_global_required_permissions(request),
obj=obj,
login_url=self.login_url,
redirect_field_name=self.redirect_field_name,
return_403=self.return_403,
return_404=self.return_404,
)
if forbidden:
self.on_permission_check_fail(request, forbidden, obj=obj)
if forbidden and self.raise_exception:
raise PermissionDenied()
return forbidden
django ๋ด์ฅ crud ๋ณด๊ธฐ์์ global_required_permissions
๋ฐ required_permissions
.
class ResourceDeleteView(GlobalPermissionRequiredMixin, DeleteView):
...
global_permission_required = [app.delete_resource]
permission_required = [app.view_resource]
...
์ด ์๋ฃจ์
์ User
๋ฆฌ์์ค ์ญ์ ์ ๋ํ ์ ์ญ ๊ถํ์ด ์๋ค๋ ๊ฒ์ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค. ์ด ๊ถํ์ django ์ธ์ฆ ๋ชจ๋ธ์์ Group
์ํด ๋ถ์ฌ๋ ์ ์์ต๋๋ค(์ด ๋ฌธ์ ์ ๋งฅ๋ฝ์์ ์ญํ ). ๊ทธ๋ฌ๋ ๊ทธ๋ django ์ธ์ฆ ๋ชจ๋ธ์์ view_resource
Permission
๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ ๊ฐ์ฒด๋ฅผ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ๋ฆฌ์์ค๋ง ์ญ์ ํ ์ ์์ต๋๋ค. ์ด๊ฒ์ด django Guardian์ผ๋ก ์ญํ ์ ๊ตฌํํ๋ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ด ๋ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์์ง์๊ฐ๋ฝ์ ์น์ผ์ธ์ฐ๋ฉด ์ ์ฝ๋์ ์ถฉ๋ ์๋ ์ฝ๋ ๋ฒ์ ์ผ๋ก ํ ๋ฆฌํ์คํธ๋ฅผ ์ด ๊ฒ์ ๋๋ค.
์ ๋ง ํฅ๋ฏธ๋ก์ด ์ ๊ทผ @jokiefer. ๋๋ ๊ทธ๊ฒ์ ์ข์ํ๋ค. ๋๋ ์๋ ๊ทธ ๋ผ์ธ์ ๋ฐ๋ผ guardian
๋ฅผ ๊ตฌํํ๋ ค๊ณ ํ๋ค. ์ฌ์ฉ์๋ ์ ์ญ view
๋๋ edit
๊ถํ์ด ํ์ํ์ง๋ง ํน์ ๊ฐ์ฒด์ ์ก์ธ์คํ๋ ค๋ฉด view
๋๋ edit
์ ๋ํ ๊ฐ๋ณ ๊ถํ์ด ํ์ํ์ต๋๋ค. ์ ์ญ ๊ถํ์ ๊ฐ์ฒด ๊ถํ์ด ์ค์ํ์ง ์์ ํ์ฑํ ๊ถํ๋ณด๋ค ๋ ๋ง์ ํ์๋ฅผ ์๊ตฌํ ๊ฒ์
๋๋ค. ๋ถ๋ช
ํ ๊ทธ๊ฒ์ ์ค์ ๋ก ์๋ํ์ง ์์์ผ๋ฏ๋ก ๋๋ ์ผ์ ์ฌ๊ตฌ์ฑํ์ต๋๋ค.
์ํ์ด ์ด๋ฅผ ํ์ฉํฉ๋๊น? ์ฆ, ์ ์ญ delete
๊ถํ์ด ํ์ํ์ง๋ง ์ค์ ๋ก delete
๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๊ฐ์ฒด ๊ธฐ๋ฐ delete
๊ถํ๋ ํ์ํฉ๋๋ค. ๊ทํ์ ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ธ๋ก๋ฒ delete
๊ฐ ํ์ํ๊ณ ๊ฐ์ฒด๋ณ view
? ์ฝ๊ฐ์ ๋ถ์ผ์น์
๋๊น?
@dwasyl
์ํ์ด ์ด๋ฅผ ํ์ฉํฉ๋๊น?
์, ์ด๊ฒ์ ๊ทํ์ ์ ๊ทผ ๋ฐฉ์์ ์ ํฉํฉ๋๋ค.
๊ทธ๋ฌ๋ ๋๋ ์์ ์ํ์ ์ด์ ์ ๋ง์ถ์ง ์์์ต๋๋ค. ์ฐ๋ฆฌ ํ๋ก์ ํธ์์๋ ๊ฐ๋ฅํ ํ ๊ฐ๋จํ acl
์ฑ(AccessControlList)์ ๊ตฌํํฉ๋๋ค. ์ด ์ฑ์๋ cl ์ด๋ผ๋ ํ๋์ ํต์ฌ ๋ชจ๋ธ์ด ์์ต๋๋ค. ์ด ๋ชจ๋ธ์ atomic
๋ณดํธ์ ๊ถํ์ ์ถ์ํ์
๋๋ค. ์ฌ์ฉ์ ์งํฉ, ๊ถํ ์งํฉ, ์ก์ธ์ค ๊ฐ๋ฅํ ๊ฐ์ฒด ์งํฉ์ ์ ์ฅํฉ๋๋ค. ์ด ๋ชจ๋ธ ๋ค์ ์จ๊ฒจ์ง ๋ง๋ฒ์ ์ผ๋ถ ์ ํธ์์ ๊ตฌํ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด ownable_models_handling.py ๋ ๋ณดํธ์ ๊ถํ์ผ๋ก ์ก์ธ์คํ ์ ์๋ ๋ค๋ฅธ ๋ชจ๋ ๋ชจ๋ธ์ ๋์ ์ผ๋ก ์ ํธ๋ฅผ ์ถ๊ฐํ๋ ์ผ๋ฐ ์ ํธ์
๋๋ค. ๋ ๋ง์ ๋ชจ๋ธ์ ํ๋ณดํ๋ ค๋ฉด AccessControlList
๋ชจ๋ธ์ ์ m2m ํ๋๋ฅผ ๊ตฌํํ๋ฉด ๋ฉ๋๋ค. ์ด ํ๋๋ ์๋์ผ๋ก ์๋ํ๋ ค๋ฉด ์ ํ accessible_MODELNAME
์ ํจ๊ป ํธ์ถ๋์ด์ผ ํฉ๋๋ค. acl_handling.py ์๋ ์ฃผ์ด์ง AccessControlList
๊ธฐ๋ฐ์ผ๋ก ๋ณดํธ์ ๊ถํ์ ์ถ๊ฐ/์ ๊ฑฐํ๋ ๊ตฌํ์ด ์์ต๋๋ค. ๊ทธ๊ฒ์ผ๋ก ์ฐ๋ฆฌ๋ ๊ฐ๋์ธ ์ฝ์ด๋ฅผ ์์ ํ ํ์๊ฐ ์์ต๋๋ค.
์ด cl ์ฑ์ด ์์ ์ํ๋ณด๋ค ๋ ๋์์ด ๋ ์ ์์ต๋๋ค. acl
์ฑ์ ๋ํ ๋ช ๊ฐ์ง ์ถ๊ฐ ์์
์ผ๋ก guadian(๊ฐ๋์ธ์ ์ํ ์ต์์ ์ฑ ์๋ฃจ์
)์ ์ญํ ์ ์ถ๊ฐํ๋ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ ์ํด ์ฝ๋์์ ์์์์ฑํ ์ ์์ต๋๋ค.