پرش به محتویات

۸. 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 است - اما تحویل شده، پس در هیچ دری نمی‌تواند آن را ویرایش کند.