۸. Policyها¶
همهی آنچه تا اینجا دیدیم یک مجوز و یک دامنه بود، و برای تصمیم گرفتن کدی لازم نداشت. یکی از قانونهای فروشگاه دربارهی کسی که میپرسد نیست، دربارهی خود سفارش است: هیچ کس سفارش را بعد از تحویل ویرایش نمیکند. این یک policy است:
"""
A rule no permission can say: nobody edits an order once it is delivered.
Everything else - view, create, approve, print an invoice - is decided by the
permission and its scope, with no code.
"""
from clearance.policies import BasePolicy
from clearance.registry import registry
from shop.models import Order
class OrderPolicy(BasePolicy):
model = Order
codename = 'order'
def can_edit(self, user, obj=None):
if not self.has_within_scope(user, 'edit', obj):
return False
return obj is None or obj.status != Order.Status.DELIVERED
order_access = registry.register(OrderPolicy)
- از مدلی که policy ندارد از طریق
ModelPolicyپرسیده میشود: مجوزش، در دامنهاش. policy فقط برای قانونی نوشته میشود که هیچ مجوزی نمیتواند بگوید. - هر hook یک
can_<action>است.has_within_scopeهمان مجوز و دامنه است - چیزی که مدل بدون policy جواب میداد - و hook قانون خودش را بعد از آن اضافه میکند. obj=Noneپرسشی است که از یک فهرست، قبل از هر ردیفی، پرسیده میشود: «اصلاً میتوانند سفارشها را ویرایش کنند؟»
آن را جایی ثبت کنید که موقع بالا آمدن پروژه import شود - فروشگاه آن را در
ready() اپ خودش import میکند:
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
class ShopConfig(AppConfig):
name = 'shop'
verbose_name = _('Shop')
default_auto_field = 'django.db.models.BigAutoField'
def ready(self) -> None:
from shop import policies # noqa: F401 - registers the order policy
پرسیدن از آن¶
همهی درها از policy میپرسند - پنل ادمین، viewهای Django و API - و یک پروژه هم میتواند:
from shop.policies import order_access
order_access.policy.allows(user, 'edit', order)
order_access.policy.authorize(user, 'edit', order) # PermissionDenied if not
south_manager مجوز order_edit را در شعبهی خودش دارد، و فرش مال South است -
اما تحویل شده، پس در هیچ دری نمیتواند آن را ویرایش کند.