_در این سوال قصد داریم برای یک سایت تولید کارت پستال امکان فارسی کردن ارقام را بگذاریم._
شرکتی خدمات کارت پستال ارائه میدهد. این شرکت به تازگی سایتی ساختهاست که با وارد کردن متنی که میخواهید، میتوانید کارت پستال آن را به صورت `html` مشاهده کنید.
اما یکی از مشکلاتی که دارد ارقام انگلیسی است. به همین دلیل تصمیم گرفتهاست که تمام ارقام انگلیسی از 0 تا 9 داخل متن را، هنگام نمایش به فارسی تبدیل کند و نمایش دهد.
پروژه اولیه را میتوانید از [اینجا](http://s8.picofile.com/file/8339634018/persian_digits_initial.zip.html) دانلود کنید.
ساختار پروژه به شکل زیر است:
```
├── Company
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
├── postal_card
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── static
│ │ └── CSS
│ │ └── intro.css
│ ├── templates
│ │ └── postal_card.html
│ ├── templatetags
│ │ ├── __init__.py
│ │ └── filters.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── requirements.txt
```
### جزئیات
اپ اصلی پروژه `postal_card` است که داخل آن کدهایی که کارت پستال را تولید میکنند وجود دارد.
همچنین پروژه دارای یه `url` اصلی است که کارت پستال را تولید میکند و آدرس آن `postal_card/` است که یک پارامتر به نام `text` میگیرد و مقدار آن متن داخل کارت پستال را مشخص میکند.
برای مثال آدرسهای `postal_card/?text=this-is-card-postal1/` و `postal_card/?text=this%20is%card-postal%20with%20spaces/` به ترتیب متنهای `this-is-card-postal1` و `this is card-postal with spaces` تولید میکنند.
حال وظیفهی شما تبدیل ارقام انگلیسی داخل متن به ارقام فارسی است. به عنوان مثال متن `22 شهریور روز برنامهنویس مبارک` باید به متن `۲۲ شهریور روز برنامهنویس مبارک` تبدیل شود.
اما با توجه به اینکه نمیخواهیم به کدهای `view` و `url` مان دست بزنیم و منطق پشت کد دستنخوره باقی بماند، شما باید تغییرات را در فایلهای `templates/postal_card.html` و `templatetags/filters.py` داخل اپ `postal_card` قرار دهید.
# نکات
+ شما تنها مجاز به تغییر دو فایل گفته شده هستید و اگر تغییری در سایر فایلها ایجاد کنید، این تغییرات نادیده گرفته خواهد شد.
+ پس از اعمال تغییرات، کل پروژه را *Zip* کرده و ارسال کنید.
+ نام فایل *Zip* اهمیت ندارد.
### کارها:
* نوشتن Manager
* نوشتن ModelForm
* نوشتن view محاسبه قیمت نهایی سفارش
می خواهیم یک سایت خرید اینترنتی محصولات مختلف بزنیم.
در این سایت کاربران می توانند محصولات مختلف را مشاهده کرده و پس از انتخاب چند محصول فاکتور نهایی خرید خود را بینند.
بخشی از این پروژه نوشته شده است. از شما میخواهیم این پروژه را تکمیل کنید.
# پروژه اولیه
پروژه اولیه را از [اینجا](http://s9.picofile.com/file/8339632626/shop_initial.zip.html) دانلود کنید. ساختار این پروژه به شرح زیر است:
```
shop
├── app
│ ├── migrations
│ │ ├── __init__.py
│ │ └── 0001_initial.py
| ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── urls.py
│ └── views.py
| └── forms.py
├── Shop
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── requirements.txt
```
# جزئیات
در این سؤال تنها لازم است تغییراتی در `app/views.py` و `app/models.py` و `app/forms.py` ایجاد کنید.
در فایل `models.py` چهار مدل به شرح زیر وجود دارد:
۱. مدل `Category` شامل فیلدهای زیر:
* نام : `name`
۲. مدل `Product` شامل فیلدهای زیر:
* نام محصول : `name`
* دسته محصول : `category`
* توضیحات : `description`
* قیمت محصول : `price`
* موجودی انبار : `stock`
۳. مدل `Order` شامل فیلدهای زیر:
* ایمیل سفارش دهنده : `email`
* آدرس سفارش دهنده : `address`
۴. مدل `OrderItem` شامل فیلدهای زیر:
* سفارش مربوطه : `order`
* محصول سفارش داده شده : `product`
* تعداد : `quantity`
مواردی که باید انجام دهید:
### ۱.نوشتن منیجر
یک منیجر جدید به نام `available` برای مدل `Product` بنویسید به طوری که فقط کالاهایی را که در انبار موجودند برگرداند.
##### توجه
منیجر (objects) باید همانند سابق منیجر پیش فرض باقی بماند.
```
>>> Product.objects.all()
<QuerySet [<Product: pc>, <Product: mouse>, ...]>
>>> Product.available.all()
<QuerySet [<Product: pc>, ...]>
>>> Product.available.filter(price__gt=20)
<QuerySet [<Product: pc>, <Product: keyboard>, ...>
```
### ۲.نوشتن فرم
در این قسمت باید یک مدل فرم برای مدل `Product` بنویسید. برای این کار، فایل `apps/forms.py` دارای یک کلاس `ProductForm` است که باید آن را پیادهسازی کنید. کالاهایی که به وسیلهی این فرم ساخته میشوند باید ویژگیهای زیر را دارا باشند:
* قیمت کالا از 1000 نباید بیشتر باید. در صورت بیشتر بود این قیمت از 1000، باید یک `ValidationError` با پیام `Product is too expensive` پرتاب شود.
* طول توضیحات کالا باید از 20 کاراکتر بیشتر باشد. در صورتی که این طول کمتر یا مساوی 20 باشد، باید یک `ValidationError` با پیام `Product must have a good description` پرتاب شود.
### ۳.نمایش قیمت نهایی یک `order`
در این قسمت باید view محاسبه قیمت نهایی `order` را (`checkout`) طوری تغییر دهید که قیمت نهایی یک `order` مشخص (`int:pk`) را به صورت یک خروجی JSON به شکل زیر برگرداند.
```json
{"total_price": "12.31"}
```
##### توجه
+ این مقدار از نوع `Decimal` می باشد و باید تا دو رقم اعشار مقدار آن حفظ شود.
+ نیازی به تغییر stock پس از checkout نمی باشد و تضمین می شود که در تست ها تعداد کالای سفارش داده شده برابر و یا کمتر از موجودی کالا باشد.
+ اگر فاکتوری با ID مورد نظر موجود نبود خطای `404` برگردانید.
# نکات
+ شما تنها مجاز به تغییر در `app/views.py` و `app/models.py` و `app/forms.py` هستید.
اگر تغییری در سایر فایلها ایجاد کنید، این تغییرات نادیده گرفته خواهد شد.
+ پس از اعمال تغییرات، کل پروژه را Zip کرده و ارسال کنید.
+ نام فایل Zip اهمیت ندارد.
_در این سوال قصد داریم به کمک کتابخانه DjangoRestFramework یک RESTful API برای وبلاگ خود طراحی کنیم._
می خواهیم یک API برای وبلاگ خود طراحی کنیم
به طوری که کاربران بتوانند از طریق این API پست ها و کامنت های
خود را مدیریت کنند و همچنین ادمین وبلاگ بتواند
به تمام فعالیت ها نظارت داشته باشد
و در صورت لزوم دست به کار شده و خودی نشان دهد.
### پروژه اولیه
پروژه اولیه را از [اینجا](http://s8.picofile.com/file/8339634242/rest_api_initial.zip.html) دانلود کنید. ساختار این پروژه به شرح زیر است:
```
blog
├── app
│ ├── migrations
│ │ ├── __init__.py
│ │ └── 0001_initial.py
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── urls.py
│ ├── serializers.py
│ ├── permissions.py
│ └── views.py
├── Blog
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── requirements.txt
```
### جزئیات
در فایل `models.py` دو مدل به شرح زیر وجود دارد:
۱. مدل `Post` شامل فیلدهای زیر:
* نویسنده : `owner`
* عنوان : `title`
* متن پست : `body`
* زمان انتشار پست : `created`
* زمان ویرایش پست : `updated`
۲. مدل `Comment` شامل فیلدهای زیر:
* نویسنده : `owner`
* متن کامنت : `body`
* پست مربوطه : `post`
* زمان انتشار کامنت : `created`
* زمان ویرایش کامنت : `updated`
در فایل
`views.py`
چهار
`view`
به شرح زیر وجود دارد:
۱. کلاس **`PostList`**
`GET`:
لیست تمام پست ها را به صورت یک خروجی
`JSON`
به فرمت زیر بر می گرداند.
```json
[
{
"title": "test",
"body": "test_body",
"created": "2018-07-18T11:27:40.074000Z",
"owner": "admin"
},
{
"title": "test",
"body": "test_body",
"created": "2018-07-18T11:28:00.152000Z",
"owner": "test_author"
},
...
]
```
`POST`:
عنوان و متن پست را به عنوان ورودی به صورت
`JSON`
می پذیرد و در صورتی که کاربر از قبل لاگین کرده باشد یک پست جدید به نام این کاربر می سازد.
۲. کلاس **`PostDetail`**
`GET`:
جزئیات یک پست را به صورت یک خروجی
`JSON`
به فرمت زیر بر می گرداند.
لیستی از لینک کامنتهای یک پست نیز در این خروجی قرار دارد.
```json
{
"title": "test",
"body": "test_body",
"created": "2018-07-18T11:26:53.044000Z",
"updated": "2018-07-18T11:26:53.044000Z",
"owner": "admin",
"comment_set": [
"http://localhost:8000/api/comments/1/",
"http://localhost:8000/api/comments/10/"
]
}
```
`PUT`:
عنوان و متن پست را به عنوان ورودی به صورت
`JSON`
می پذیرد و در صورتی که کاربر **مالک** پست و یا **ادمین** باشد پست را ویرایش می کند.
`DELETE`:
در صورتی که کاربر **مالک** پست و یا **ادمین** باشد پست را حذف می کند.
۳. کلاس **`CommentDetail`**
`GET`:
جزئیات یک کامنت را به صورت یک خروجی
`JSON`
به فرمت زیر بر می گرداند.
لینک پست مربوطه نیز در این خروجی قرار دارد.
```json
{
"post": "http://localhost:8000/api/posts/1/",
"owner": "hamid",
"body": "test_body",
"created": "2018-07-18T11:28:47.400000Z",
"updated": "2018-07-18T11:28:47.401000Z"
}
```
`PUT`:
متن کامنت را به عنوان ورودی به صورت
`JSON`
می پذیرد و در صورتی که کاربر **مالک** کامنت و یا **ادمین** باشد کامنت را ویرایش می کند.
`DELETE`:
در صورتی که کاربر **مالک** کامنت و یا **ادمین** باشد کامنت را حذف می کند.
۴. کلاس **`AddComment`**
`POST`:
متن کامنت را به عنوان ورودی به صورت
`JSON`
می پذیرد و در صورتی که کاربر از قبل لاگین کرده باشد یک کامنت جدید به نام این کاربر و برای پست انتخاب شده می سازد.
اما کارهایی که شما باید تو این پروژه انجام بدید:
شما باید در دو فایل
**`serializers.py`**
و
**`permissions.py`**
کلاس هایی که در این
`view`
ها استفاده شده و پیاده سازی نشده اند را طوری پیاده سازی کنید که
`view`
ها طبق توضیحات داده شده عمل کنند.
### نکات
+ شما تنها مجاز به تغییر در `app/serializers.py` و `app/permissions.py` هستید.
اگر تغییری در سایر فایلها ایجاد کنید، این تغییرات نادیده گرفته خواهد شد.
+ در هر بخشی از پروژه که
`view`
ها یک ورودی به فرمت
`json`
میپذیرند، منظور فرمتی به صورت زیر است:
```json
{
"title": "test",
"body": "test_body"
}
```
### آنچه باید آپلود کنید
+ پس از اعمال تغییرات، کل پروژه را Zip کرده و ارسال کنید.
+ نام فایل Zip اهمیت ندارد.
کار ها:
+ نوشتن Decorator برای view ها (نمره: ۶۵ درصد)
+ نوشتن view برای فعال کردن پروژه فعلی (نمره: ۱۵ درصد)
+ نوشتن تابع has_permission (نمره: ۲۰ درصد)
---------------------------------------------------------------------------------------------------------
یک شرکت نرمافزاری میخواهد برای خود یک سیستم مدیریت پروژه بنویسد. بدین منظور سایتی با قابلیت های زیر طراحی شده است:
+ در این سایت چندین پروژه میتواند وجود داشته باشد.
+ هر پروژه میتواند چندین عضو داشته باشد.
+ هر کاربر میتواند در چند پروژه در نقش های مختلف عضویت داشته باشد.
از این [لینک](http://s9.picofile.com/file/8339632884/myproject_initial.zip.html) میتوانید source code های پروژه را دانلود کنید.
ساختار این پروژه به شکل زیر است:
```
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:
این 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](https://en.wikipedia.org/wiki/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 ها استفاده میشود که یک آرگومان optional به نام `permissions` دریافت میکند. در صورتی که این آرگومان به decorator پاس داده شود باید به صورت یک لیست باشد. برای مثال:
```python
@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) بازگردانید.
# نکات
+ شما تنها مجاز به تغییر در فایل هایی هستید که در ساختار بالا با فلش مشخص شده اند. اگر تغییری در سایر فایلها ایجاد کنید، این تغییرات نادیده گرفته خواهد شد.
+ در فایل `models.py` میتوانید به تعداد دلخواه به هر مدلی تابع اضافه کنید. اما field ها و نام های مدل ها را تغییر ندهید.
+ پس از اعمال تغییرات، کل پروژه را Zip کرده و ارسال کنید.
+ نام فایل Zip اهمیت ندارد.
همه چی از uber شروع شد. ایده ی خوبی که رانندگان را به مسافران وصل میکرد و هر کسی هر جایی بود به سرعت میتوانست برای خودش تاکسی درخواست دهد. مدتی نگذشت که برنامهنویس های داخل کشور عزیزمان هم از این سرویس ایده گرفتند و شروع به پیاده سازی مشابه آن در ایران کردند. در حال حاضر چندین سرویس درخواست آنلاین تاکسی وجود دارد که در تهران و چند شهر دیگر مشغول سرویس دهی به مسافرین هستند و روز به روز هم گسترش بیشتری میابند و اشتغالزایی زیادی را نیز به وجود آوردهاند. حالا با توجه به بازار داغ این سرویس ما نیز میخواهیم یک سرویس مشابه ایجاد کنیم. اسمش هم `cabin` گذاشتهایم.
شما میتوانید پروژه کابین را از [اینجا](http://s9.picofile.com/file/8339633376/cabin_initial.zip.html) دانلود کنید.
همانطور که در فایل ها میبینید یک app به نام cabin وجو دارد. در فایل models.py هشت مدل به شرح زیر وجود دارد:
+ مدل Account: اکانت که به یک مدل دیگر اعم از راننده یا مسافر یا مدیر سیستم وصل است و شامل فیلد های زیر است
+ first_name: نام شخص
+ last_name: نام خانوادگی شخص
+ email: ایمیل شخص
+ phone: شماره تلفن شخص
+ password: پسورد شخص
+ مدل Admin: مدیر سیستم که دسترسی هایی خاصی به سیستم دارد
+ account: اکانت ادمین که اطلاعات او را نگه میدارد
+ مدل Rider: مسافر
+ account: اکانت مسافر که اطلاعات او را نگه میدارد
+ x: طول جغرافیایی موقعیت مسافر
+ y: عرض جغرافیایی موقعیت مسافر
+ rating: امتیاز مسافر
+ مدل Driver: راننده
+ account: اکانت راننده که اطلاعات او را نگه میدارد
+ x: طول جغرافیایی موقعیت راننده
+ y: عرض جغرافیایی موقعیت راننده
+ rating: امتیاز راننده
+ active: آماده به کار بودن یا نبود راننده را نشان میدهد
+ مدل Car: خودرو
+ owner: صاحب خودرو که یک راننده است
+ car_type: نوع کلاس خودرو
+ model: سال تولید خودرو
+ color: رنگ خودرو
+ مدل RideRequest: درخواست سفر
+ rider: مسافر درخواست دهنده
+ x: طول جغرافیایی نقطه درخواست
+ y: عرض جغرافیایی نقطه درخواست
+ car_type: کلاس خودرو درخواست شده
+ مدل Ride: سفر
+ pickup_time: (زمان شروع سفر(سوار کردن مسافر
+ dropoff_time: زمان پایان سفر
+ *دو زمان بالا از نوع عدد صحیح و نشاندهنده تعداد ثانیه های گذشته از زمان تاسیس شرکت می باشند.*
+ request: درخواست سفری که این سفر به آن مربوط میشود
+ car: خودرویی که این سفر با آن انجام شده است
+ rider_rating: امتیازی که راننده به مسافر داده است
+ driver_rating: امتیازی که مسافر به راننده داده است
+ مدل Payment: پرداخت
+ ride: سفری که پرداخت برای آن انجام شده است
+ amount: مبلغ پرداخت شده برحسب تومان
+ status: وضعیت پرداخت
حال از شما میخواهیم پرس و جو (query) های زیر را روی مدل های بالا بنویسید.
**حتما قبل شروع نوشتن کد، تذکرات انتهای سوال را بخوانید!**
#### ۱. کل مبلغ دریافتی توسط راننده ای با شناسه برابر با x.
+ در این سوال status اهمیتی ندارد و نتیجه را میتوانید به شکل یک dict برگردانید.
```json
{'payment_sum': value }
```
#### ۲. لیست همه سفر های یک مسافر با شناسه x.
#### ۳. تعداد سفر هایی که طول آنها (از نظر زمانی) بیشتر از t بوده است.
+ نتیجه این پرسوجو یک عدد است.
#### ۴. لیست همه راننده هایی که در فاصله کمتر یا مساوی از r حول نقطه (x,y) قرار دارند و فعال (آماده به کار) نیز هستند.
#### ۵. لیست رانندگانی که یک ماشین کلاس A **یا** یک ماشین با رنگ c دارند **و** حداقل n سفر انجام داده اند.
#### ۶. لیست مسافرانی که x سفر یا بیشتر داشته اند و در مجموع بیشتر از t تومان پرداخت کرده اند.
#### ۷. لیست رانندگانی که حداقل یک سفر داشته اند که در آن سفر اسم راننده با اسم مسافر یکسان بوده است.
+ *در این لیست نباید رانندهی تکراری وجود داشته باشد.*
#### ۸. لیست **همه** راننده ها و یک ستون دیگر با نام `n` که نشان دهنده ی تعداد سفر هایی است که در آنها نام خانوادگی راننده با نام خانوادگی مسافر یکسان بوده است.
#### ۹. لیست **همه** راننده ها به همراه یک ستون دیگر به نام `n` که تعداد سفر هاییست که در آن سفر ها ماشین مدل x یا به بالا (توجه کنید که مدل با نوع متفاوت است!) بوده است **و** طول سفر بیشتر از t ثانیه بوده است.
خروجی نمونه:
```
<QuerySet [{'id': 1, 'n': 8}, {'id': 2, 'n': 1},....]>
```
* طول این لیست به تعداد همه راننده ها است که در هر عنصر آن id راننده و n (با تعریف بالا) قرار دارد.*
#### ۱۰. لیست **همه** ماشین ها و یک ستون اضافه شده به آن به نام `extra` از نوع عدد صحیح که مقدار این ستون با توجه به نوع ماشین (`car_type`) به شرح زیر تعریف میشود.
+ اگر نوع ماشین `A` بود تعداد سفر های انجام شده با آن ماشین در ستون extra قرار میگیرد.
+ اگر نوع ماشین `B` بود مجموع طول سفر های انجام شده با آن ماشین در ستون extra قرار میگیرد.
+ اگر نوع ماشین `C` بود مجموع مبلغ سفر های انجام شده با آن ماشین در ستون extra قرار میگیرد.
## **تست نمونه:**
در فایل های اولیه ای که دانلود کردید یک سری داده اولیه به عنوان نمونه قرار داده شده است. همچنین ۵ تست نمونه برای ۵ پرسوجو اول بر اساس داده های اولیه قرار داده شده است که میتوانید قبل از فرستادن سوال در سایت، این تست ها را ببینید تا با نحوه داوری ما آشنا شوید و از پاسخ خود اطمینان حاصل نمایید.
تست ها را میتوانید با دستور زیر اجرا کنید:
```bash
python manage.py test
```
## **تذکرات:**
+ یک فایل به نام `queries.py` وجود دارد که برای هر سوال یک تابع در نظر گرفته شده است. شما کد های خود را باید در این فایل بنویسید و QuerySet مربوطه را بازگردانید.
+ برای نمونه تابع `query_0` در پاسخ به پرس و جویِ «لیست همه ی رانندگانی که رتبهی آنها بیشتر از x است.» کامل شده است که شما نیز باید مشابه همین تابع بقیه توابع را کامل کنید.
```python
def query_0(x):
q = Driver.objects.filter(rating__gt=x)
return q
```
+ در سوالاتی که در صورت سوال مقداری به صورت متغییر ذکر شده است(مانند x در مثال بالا)، متغییر مورد نظر در آرگومان های ورودی تابع در نظر گرفته شده است. شما خود نباید آرگومان های ورودی تابع را تغییر دهید.
+ در تمام سوالات به جز سوالاتی که خروجی نمونه برای آنها مشخص شده است، همان طور که ذکر شد، خروجی شما یک شیء از نوع QuerySet با المان هایی از جنس گفته شده در اول سوال باید باشد. یعنی در واقع خود query را return کنید.
+ برای مثال اگر سوال گفته باشد «لیست ماشین هایی که....» خروجی شما به شکل زیر باید باشد:
```
<QuerySet [<Car: Car object>, <Car: Car object>,.....]>
```
+ در سوالات دیگر نیز که خروجی مشخص شده است، باز نتیجه یک QuerySet است ولی شامل همه فیلد های مدل مورد نظر نمیشود و فقط فیلد های خواسته شده با نام خواسته شده باید در آن قرار داشته باشد.
+ در هیچ کدام از پرس و جوی های خواسته شده ترتیب مهم نیست.
### فایل آپلودی
پس از نوشتن کد، کل پروژه را *zip* کرده و ارسال کنید. توجه کنید که هر کدی که خارج از فایل `queries.py` باشد، در هنگام داوری حذف خواهند شد.