احتمالا شما هم تا به حال از یک فروشگاه آنلاین خرید کردهاید. در هر فروشگاه آنلاین یک سبد خرید یا `cart` وجود دارد که محصولات انتخاب شده در آن نمایش داده میشوند و برای هر محصول میتوان بعضی خصوصیات آن محصول مانند تعداد، رنگ و ... را تغییر داد.
حال ما میخواهیم یک فروشگاه آنلاین بنویسیم و قسمتی از پروژه را نیز نوشتهایم و از شما میخواهیم در نوشتن فرمِ سبد خرید به ما کمک کنید. پروژهی فعلی را میتوانید از [این لینک](/problemset/assignments/4367/download_problem_initial_project/33475/) دانلود کنید. ساختار فایلهای این پروژه به صورت زیر است:
```
online shop
├── challenge2
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
├── requirements.txt
├── shop
│ ├── admin.py
│ ├── apps.py
│ ├── <mark class="yellow" title="این فایل را تغییر دهید"> > forms.py < </mark>
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ └── __init__.py
│ ├── models.py
│ └── views.py
├── templates
│ └── cart_form.html
└── tests
└── testsample.py
```
در پروژه یک `app` به نام `shop` و در آن دو مدل `Color` و `Product` وجود دارد.
در فایل `forms.py` یک فرم با نام `CartForm` وجود دارد که شما باید این کلاس را به شکل زیر تکمیل کنید.
**توجه**: در ورودی `kwargs` تابع `__init__` یک کلید به نام `items` وجود دارد که لیست `product` ها را نشان میدهد.
#### **اضافه کردن فیلدها**
شما باید به ازای هر `product` ای که به فرم شما پاس داده میشود، دو فیلد تعداد و رنگ را به شکل زیر قرار دهید:
+ **تعداد:** این فیلد باید از نوع `IntegerField` باشد و نام آن `number_<product.id>` باشد که در آن *<product.id>* آیدی آن محصول است. برای این فیلد، باید مقدار پیشفرض ۱ را در نظر بگیرید. و `label` آن هم باید نام محصول باشد.
+ **رنگ:** این فیلد از نوع `ChoiceField` میباشد و نام آن `color_<product.id>` است که در آن *<product.id>* آیدی آن محصول است. این فیلد لیستی از رنگهای موجود برای محصول خاص را نشان میدهد. مقدار `label` این فیلد هم باید `'color'` باشد. تضمین میشود که هیچ محصولی بدون رنگ نیست.
موارد خواسته شده باید در تابع `__init__` به `self.fields` اضافه شوند. همچنین به ازای هر دو مورد بالا مقدار `required` باید `False` باشد.
توجه کنید که هر دو این فیلدها در نهایت حتما باید مقدار داشته باشند بدین معنی که اگر در `request.POST` داده برای یک فیلد فرستاده نشد، باید خودتان برایش مقداری قرار دهید. برای فیلدهای "تعداد" مقدار ۱ و برای فیلدهای "رنگ"، کوچکترین رنگ موجود در لیست رنگهای آن کالا (از نظر الفبایی) باید قرار بگیرد.
#### برای مثال:
```
>>> product.id
5
>>> product.colors_available
{'red', 'blue', 'white'}
```
حال یک درخواست POST با داده های خالی `{}` ارسال میشود. در این صورت باید بعد از ایجاد فرم و صدا شدن تابع ()is_valid، متغییر cleaned_data به شکل زیر باشد:
```
{'number_5' = 1, 'color_5' = 'blue'}
```
زیرا رنگ `blue` از نظر الفبایی از دو رنگ دیگر کوچکتر است.
در فایل `views.py` یک تابع به نام `make_json` قرار دارد که cleand_data فرم مورد نظر را به شکل json با فرمت خاص برمیگرداند. نیازی نیست شما در این تابع تغییری ایجاد کنید یا از آن استفاده کنید.
## تست نمونه
در فایلهای اولیهای که دانلود کردید یکسری داده اولیه به عنوان نمونه قرار داده شده است. میتوانید قبل از فرستادن سوال در سایت، این تستها را ببینید تا با نحوه داوری ما آشنا شوید و از پاسخ خود اطمینان حاصل نمایید.
تستها را میتوانید با دستور زیر اجرا کنید:
```shell terminal terminal
python manage.py test
```
## نکات
+ شما تنها مجوز ایجاد تغییرات در`forms.py` را دارید و **تمامی تغییرات دیگر شما** در فایلهای پروژه **نادیده گرفته خواهند شد.**
+ فراموش نکنید که میتوانید با مطالعهی `testsample.py` با روش تست کردن مدلها آشنا شوید.
## آنچه باید آپلود کنید
این سوال از نوع سوالات چندفایلی است. برای حل سوال میتوانید پروژه را در قالب یک فایل *ZIP* که شامل کلیه فایلهای موجود در پروژه است، ارسال کنید.