روز
۹۰۱۲۳۴۵۶۷۸۹۰۹۰۱۲۳۴۵۶۷۸۹۰
روز
ساعت
۹۰۱۲۳۴۵۶۷۸۹۰۹۰۱۲۳۴۵۶۷۸۹۰
ساعت
دقیقه
۹۰۱۲۳۴۵۶۷۸۹۰۹۰۱۲۳۴۵۶۷۸۹۰
دقیقه
ثانیه
۹۰۱۲۳۴۵۶۷۸۹۰۹۰۱۲۳۴۵۶۷۸۹۰
ثانیه

یک شرکت نرم‌افزاری می‌خواهد برای خود یک سیستم مدیریت پروژه بنویسد. بدین منظور سایتی با قابلیت‌های زیر طراحی شده است:

  • در این سایت چندین پروژه می‌تواند وجود داشته باشد.
  • هر پروژه می‌تواند چندین عضو داشته باشد.
  • هر کاربر می‌تواند در چند پروژه در نقش‌های مختلف عضویت داشته باشد.

پروژه اولیه

پروژه اولیه را از این لینک دانلود کنید. ساختار این پروژه به شرح زیر است:

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
Plain text

جزئیات

مدلِProjectMembership که در فایل models.py نوشته شده است، عضویت یک فرد را در یک پروژه به همراه نقش او در پروژه نشان می‌دهد.

در فایل views.py نیز چندین view وجود دارد که اعمال مختلف قابل انجام روی پروژه را پیاده‌سازی کرده است.

این سایت بدین شکل کار می‌کند که همواره فقط یکی از پروژه‌های کاربر به عنوان "پروژه فعلی" او انتخاب شده است که از طریق صفحه‌ی index نیز قادر به مشاهده این پروژه هستیم و تمامی اعمال مختلف مانند حذف پروژه و غیره، روی همین پروژه فعلی انجام می‌شوند.

نکته: یک کاربر در یک پروژه فقط یک بار و با یک نقش می‌تواند عضو باشد. بنابراین واژه‌های "پروژه‌ی فعلی" و "عضویت فعلی" به یک معنا هستند.

حال از شما می‌خواهیم تغییرات زیر را در این پروژه انجام دهید.

۱. نوشتن 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(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

یک فایل به نام 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')
Python
sample.py

در این decorator باید کارهای زیر را به ترتیب انجام دهید:

۱. ابتدا باید چک کنید که آیا برای کابر مورد نظر پروژه‌ای وجود دارد یا خیر.

  • اگر پروژه‌ای وجود نداشت یک خطای ۴۰۴ با متن "No projects found" بازگردانید.
  • در غیر این صورت، request.memberships را برابر queryset عضویت‌های کاربر قرار دهید.

۲. سپس باید چک کنید که آیا یک پروژه به عنوان پروژه فعلی برای کاربر وجود دارد یا خیر.

  • اگر پروژه‌ای به عنوان پروژه فعلی وجود نداشت، عضویتی با کمترین id را به عنوان عضویت فعلی او انتخاب کنید. سپس request.current_membershipرا برابر عضویت فعلی کاربر قرار دهید.

۳. request.project را برابر پروژه فعلی کاربر قرار دهید.

۴. اگر آرگومان permissions وجود داشت باید بررسی کنید که آیا کاربر در عضویت فعلی خود، دسترسی‌های لازم را دارد یا خیر. برای این کار می‌توانید از تابع has_permission که در قسمت قبل نوشتید استفاده کنید.

  • اگر دسترسی وجود نداشت باید یک خطای ۴۰۳ (Forbidden) بازگردانید.

تست نمونه

در فایل‌های اولیه‌ای که دانلود کردید یکسری داده اولیه به عنوان نمونه قرار داده شده است. می‌توانید قبل از فرستادن سوال در سایت، این تست‌ها را ببینید تا با نحوه داوری ما آشنا شوید و از پاسخ خود اطمینان حاصل نمایید.

تست‌ها را می‌توانید با دستور زیر اجرا کنید:

python manage.py test
Shell
terminal

نکات

  • شما تنها مجاز به تغییر در projects/decorators.py، projects/models.py و projects/activation_view.pyهستید. اگر تغییری در سایر فایل‌ها ایجاد کنید، این تغییرات نادیده گرفته خواهد شد.
  • در فایل models.py می‌توانید به تعداد دلخواه‌تان، به هر مدلی تابع اضافه کنید. اما فیلدها و نام‌های مدل‌های موجود را تغییر ندهید.
  • فراموش نکنید که می‌توانید با مطالعه‌ی testsample.py با روش تست کردن آشنا شوید.

نحوه ارسال

یک فایل ZIP حاوی همه‌ی فایل‌های پروژه، آپلود کنید. نام فایل ZIP اهمیتی ندارد.


ارسال پاسخ برای این سؤال
فایلی انتخاب نشده است.