یک شرکت نرمافزاری میخواهد برای خود یک سیستم مدیریت پروژه بنویسد. بدین منظور سایتی با قابلیتهای زیر طراحی شده است:
- در این سایت چندین پروژه میتواند وجود داشته باشد.
- هر پروژه میتواند چندین عضو داشته باشد.
- هر کاربر میتواند در چند پروژه در نقشهای مختلف عضویت داشته باشد.
پروژه اولیه
پروژه اولیه را از این لینک دانلود کنید. ساختار این پروژه به شرح زیر است:
src
├── manage.py
├── ProjectManager
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── projects
│ ├── admin.py
│ ├── apps.py
│ ├── > decorators.py <
│ ├── > models.py <
│ ├── > activation_view.py <
│ ├── templates
│ │ └── projects
│ │ └── project_home.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── requirements.txt
جزئیات
مدلِProjectMembership
که در فایل models.py نوشته شده است، عضویت یک فرد را در یک پروژه به همراه نقش او در پروژه نشان میدهد.
در فایل views.py نیز چندین view وجود دارد که اعمال مختلف قابل انجام روی پروژه را پیادهسازی کرده است.
این سایت بدین شکل کار میکند که همواره فقط یکی از پروژههای کاربر به عنوان "پروژه فعلی" او انتخاب شده است که از طریق صفحهی index
نیز قادر به مشاهده این پروژه هستیم و تمامی اعمال مختلف مانند حذف پروژه و غیره، روی همین پروژه فعلی انجام میشوند.
نکته: یک کاربر در یک پروژه فقط یک بار و با یک نقش میتواند عضو باشد. بنابراین واژههای "پروژهی فعلی" و "عضویت فعلی" به یک معنا هستند.
حال از شما میخواهیم تغییرات زیر را در این پروژه انجام دهید.
۱. نوشتن activation_view
activation_view
این view شناسهی یک پروژه را به عنوان ورودی گرفته و آن را به عنوان پروژه فعلی انتخاب میکند. بدین منظور یک field در مدل ProjectMembership
به نام is_current
در نظر گرفته شده است که باید آن را مقداردهی کرده (is_current=True
) و برای سایر عضویتها (ProjectMembership) نیز این field را False
کند.
- توجه کنید ممکن است به هر دلیلی مانند race condition، از قبل برای یک کاربر چندین عضویت با
is_current=True
وجود داشته باشد. بعد از اجرای این کد باید اطمینان حاصل شود که برای این user، فقط یک عضویت فعلی وجود دارد. - در صورتی که کاربر فعلی در پروژه با شناسه مورد نظر عضویت نداشت یا به کل پروژهای با شناسه مورد نظر وجود نداشت، باید یک پاسخ با استاتوسکد ۴۰۴ نشان دهید.
- بعد از این که پروژه مورد نظر با موفقیت به عنوان پروژه فعلی برای کاربر فعلی انتخاب شد، این view باید به صفحه
index
(یعنی آدرس/project
) redirect شود. در صفحهی index باید بتوانیم پروژه انتخاب شده را ببینیم.
۲. نوشتن تابع has_permission
has_permission
برای این بخش از سوال باید یک تابع به نام has_permission(action)
در مدل ProjectMembership
تعریف کنید. این تابع یک رشته را به عنوان ورودی دریافت میکند و بر اساس role
یک boolean بازمیگراند. انواع roleها در این مدل مشخصاند. شما باید بر اساس جدول زیر به ازای هر رشته ورودی، خروجی درست را بازگردانید. توجه کنید که ورودی تابع به صورت snake_case میباشد.
جدول زیر دسترسیهای نقشهای مختلف در این پروژه را مشخص میکند.
Action | Guest | Reporter | Developer | Master | Owner |
---|---|---|---|---|---|
create_new_issue | ✓ | ✓ | ✓ | ✓ | ✓ |
leave_comments | ✓ | ✓ | ✓ | ✓ | ✓ |
pull_project_code | ✓ | ✓ | ✓ | ✓ | |
assign_issues_and_merge_requests | ✓ | ✓ | ✓ | ✓ | |
see_a_list_of_merge_requests | ✓ | ✓ | ✓ | ✓ | |
manage_merge_requests | ✓ | ✓ | ✓ | ||
create_new_branches | ✓ | ✓ | ✓ | ||
add_new_team_members | ✓ | ✓ | |||
push_to_protected_branches | ✓ | ✓ | |||
switch_visibility_level | ✓ | ||||
remove_project | ✓ | ||||
force_push_to_protected_branches | |
۳. نوشتن Decorator
Decorator
یک فایل به نام decorators.py
نوشته شده است. شما باید در این فایل یک decorator بنویسید. این decorator در بالای همهی viewهای موجود در فایل views.py
قرار داده شده است. این decorator به شکل @projects_panel()
در بالای viewها استفاده میشود که یک آرگومان اختیاری به نام permissions
دریافت میکند. در صورتی که این آرگومان به decorator پاس داده شود باید به صورت یک لیست باشد. برای مثال:
@projects_panel(permissions=['remove_project'])
def remove_project(request):
request.project.delete()
return redirect('index')
در این decorator باید کارهای زیر را به ترتیب انجام دهید:
۱. ابتدا باید چک کنید که آیا برای کابر مورد نظر پروژهای وجود دارد یا خیر.
- اگر پروژهای وجود نداشت یک خطای ۴۰۴ با متن
"No projects found"
بازگردانید. - در غیر این صورت،
request.memberships
را برابرqueryset
عضویتهای کاربر قرار دهید.
۲. سپس باید چک کنید که آیا یک پروژه به عنوان پروژه فعلی برای کاربر وجود دارد یا خیر.
- اگر پروژهای به عنوان پروژه فعلی وجود نداشت، عضویتی با کمترین id را به عنوان عضویت فعلی او انتخاب کنید.
سپس
request.current_membership
را برابر عضویت فعلی کاربر قرار دهید.
۳. request.project
را برابر پروژه فعلی کاربر قرار دهید.
۴. اگر آرگومان permissions
وجود داشت باید بررسی کنید که آیا کاربر در عضویت فعلی خود، دسترسیهای لازم را دارد یا خیر. برای این کار میتوانید از تابع has_permission
که در قسمت قبل نوشتید استفاده کنید.
- اگر دسترسی وجود نداشت باید یک خطای ۴۰۳ (Forbidden) بازگردانید.
تست نمونه
در فایلهای اولیهای که دانلود کردید یکسری داده اولیه به عنوان نمونه قرار داده شده است. میتوانید قبل از فرستادن سوال در سایت، این تستها را ببینید تا با نحوه داوری ما آشنا شوید و از پاسخ خود اطمینان حاصل نمایید.
تستها را میتوانید با دستور زیر اجرا کنید:
python manage.py test
نکات
- شما تنها مجاز به تغییر در
projects/decorators.py
،projects/models.py
وprojects/activation_view.py
هستید. اگر تغییری در سایر فایلها ایجاد کنید، این تغییرات نادیده گرفته خواهد شد. - در فایل
models.py
میتوانید به تعداد دلخواهتان، به هر مدلی تابع اضافه کنید. اما فیلدها و نامهای مدلهای موجود را تغییر ندهید. - فراموش نکنید که میتوانید با مطالعهی
testsample.py
با روش تست کردن آشنا شوید.
نحوه ارسال
یک فایل ZIP حاوی همهی فایلهای پروژه، آپلود کنید. نام فایل ZIP اهمیتی ندارد.
ارسال پاسخ برای این سؤال