diff --git a/.travis.yml b/.travis.yml index bb026011..d672cab9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,18 @@ language: python python: -- 3.8 + - 3.8 services: -- postgresql + - postgresql install: -- psql -c 'create database django_db owner postgres;' -U postgres -- pip install -r requirements.txt + - psql -c 'create database django_db owner postgres;' -U postgres + - pip install -r requirements.txt script: -- python manage.py migrate -- python manage.py test shop/tests/ + - python manage.py migrate + - python manage.py test shop/tests/ deploy: provider: heroku api_key: - secure: mPaaMYOJ0x4W68w/MNgTMD0UgbUJL1dDSSNy/FdHjK3CygqbUhRjC0u0tT6YRJOnPY5wmv8SYvhHgo9vGnTfM5f2zSX+N/BchCD/39GbxgAfrJ2wo3KTiF8zlihs7+l7FInriWPe6lkogJD7APNkIsT24jxvrNgcKkHvGsG/stZXK4Fq/5GNRqzOHsjoqNgUIS1+8w8qWDIEb8jF24155aqiE9lTwzD1jY9tpREB4iIvTlPldM+A29mzipNxPaz0QsR5dHLzkGXK5VsWlAsyfRnnRYbqhaB4cBrX0TBBkUcSLC0Y3n2hDiKXkbRW1xD+Ho1mJZEGXXZAeJDcG2E05V+6sAEWGHqlv+ez380j8qgl2WT/XAMiAD45au9JjX5QUtJRpFTQCAnsEICeT3ekIXdRwo/i2af/L9pEUD9i48E9XY0v7yPVWGRZ/5v8j+1zPo1lLI/Wnebj0HIKku6uto+rRD7esYt7SN9JV0b6wfBX+zyl68SghBJS2qRaZnq62e4Wq38nka+PDN0z6PQhP4oxp6S8L+faPN1jCOisinhuWbVLZKTWxRJEL3/lt1LyyiTCTq1WBFbF0nDzXERfs+j8i+ZjtLZDGaNEdkCjldpkg4FL+LK6E15SF77g9hkfDx1XAdGoN7W9VW8Mrc+XQhs0L0RXpv1TFhX4JKup6Eg= - app: webapp-ivanov-shop + secure: MJLW4SX/BsuezTNmljZGWLgay+v1gdSpp1JbEu01txgPkh7WJ2lopA+A7q9kLCSx87j6lDBFld2bYv4zDW04NJ9Z4pk6fhIHjJCJwWJKDt+2za6kybq2yNwGxKaLbPWy0LNCYQNtt0n6XkMLrznjmYOhkIE/+GG5arCO4wzH4hjsxOYpPvEEu5Lh8FVjun+6/Lak3DGbs4CufxrvwFwAEDjavKPPv3v1yD/qFahY3YVPoeimjDbrRPC+9OisgWPYAkHeDiyfEVH8PHw802WgG6elrSrl00A8vUgS5rRK1cCvh5EL+B8KkifuCWq8sprYLiI1+T87iV0DpuyFH6lFg2oOoOsSVd69WpvyGdHkQE/mjXWhv0UuFfmoY6bhniKvGQCv55/Bw3O3VGcUYOt2Ys4AxDXGgUBZUelGn8QUEhp2ET0ih5HiwQmHnEU1YNYAOTkMnQbu1+w5KtkfVYX381lZ277pSI21Egqz+NuMfrhOlbtYqTrt4z14mdJYwDVmI6dQel1NkJ5O9Mzmo8f1IVlfgLGSDUENuWp1m9nXqju6o4Zk2gDJeKSzW9VyjK/BK9rVG+eu7CW5IjjNSR7nskk2zQKbo6mmG9+1fSyKll2c4JuDOY1PnxdoRp9NLnRPMZrmKmCZqb8iR6/DMvsKQkfslhCTQ6PNkca0/PKC+p4= + app: krivabokov-app run: python manage.py loaddata products.yaml && python manage.py migrate on: master diff --git a/README.md b/README.md index ecddab77..9630ccba 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,44 @@ -[![Build Status](https://app.travis-ci.com/kpdvstu/PTLab2.svg?branch=master)](https://app.travis-ci.com/kpdvstu/PTLab2) +[![Build Status](https://app.travis-ci.com/Krivabokov/PTLab2.svg?branch=master)](https://app.travis-ci.com/Krivabokov/PTLab2) # Лабораторная 2 по дисциплине "Технологии программирования" + +### Изучение фреймворка MVC + +# Цели работы: +1. Познакомиться c моделью MVC, ее сущностью и основными фреймворками на ее основе. +2. Разобраться с сущностями «модель», «контроллер», «представление», их функциональным +назначением. +3. Получить навыки разработки веб-приложений с использованием MVC-фреймворков, написания +модульных тестов к ним и интеграции приложений в конвейер CI / CD; +4. Получить навыки управления автоматизированным тестированием и разворачиванием +программного обеспечения, расположенного в системе Git, с помощью инструмента Travis CI. + +# Постановка задачи: +В работе используется учебный проект, представляющий собой простейший пример интернетмагазина, +реализованного с использованием модели MVC с помощью фреймворка Django на языке +Python. + +Необходимо доработать проект магазина, добавив в него новую функциональность и информацию в базу +данных в соответствии с типом магазина. Составить модульные тесты к проекту, постарайтесь покрыть тестами +максимально возможный объем кода. + +Тип магазина: + + Магазин предметов роскоши + +Функциональность приложения: + + В магазине имеется определенное количество товара каждого + вида. После покупки количество товара уменьшается. Если товар + закончился, его покупка должна быть невозможной. + +# Используемые языки / библиотеки / технологии +Языки: Python + +Библиотеки: django, os, sys, datetime + +Технологии: Git, Travis CI + +# Выводы по работе +В данной работе я познакомился c моделью MVC. Получил навыки веб-приложений с использованием MVC-фреймворков, написания +модульных тестов к ним. управления автоматизированным тестированием и разворачиванием +программного обеспечения, расположенного в системе Git, с помощью инструмента Travis CI. \ No newline at end of file diff --git a/shop/fixtures/products.yaml b/shop/fixtures/products.yaml index dbe7c6ab..118cbfe5 100644 --- a/shop/fixtures/products.yaml +++ b/shop/fixtures/products.yaml @@ -1,15 +1,30 @@ - model: shop.product pk: 1 fields: - name: Стол - price: 2000 + name: Дерево с кулонами (фарфор, бронза) + price: 120000 + quantity: 3 - model: shop.product pk: 2 fields: - name: Стул - price: 1000 + name: Композиция "Охота с лодки" (агат, серебро) + price: 380000 + quantity: 1 - model: shop.product pk: 3 fields: - name: Табурет - price: 500 + name: Напольные часы "Полководцы" №1 + price: 900000 + quantity: 1 +- model: shop.product + pk: 4 + fields: + name: Часы напольные "Охота" №1 + price: 850000 + quantity: 5 +- model: shop.product + pk: 5 + fields: + name: 10 томов "Великие правители Востока" + price: 4900000 + quantity: 1 diff --git a/shop/migrations/0001_initial.py b/shop/migrations/0001_initial.py index c198c783..4972ac2f 100644 --- a/shop/migrations/0001_initial.py +++ b/shop/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.8 on 2021-10-06 17:32 +# Generated by Django 4.1.3 on 2022-12-09 13:19 from django.db import migrations, models import django.db.models.deletion diff --git a/shop/models.py b/shop/models.py index 68f38c59..9254d69e 100644 --- a/shop/models.py +++ b/shop/models.py @@ -4,9 +4,10 @@ class Product(models.Model): name = models.CharField(max_length=200) price = models.PositiveIntegerField() + quantity = models.IntegerField() class Purchase(models.Model): product = models.ForeignKey(Product, on_delete=models.CASCADE) person = models.CharField(max_length=200) address = models.CharField(max_length=200) - date = models.DateTimeField(auto_now_add=True) \ No newline at end of file + date = models.DateTimeField(auto_now_add=True) diff --git a/shop/templates/shop/index.html b/shop/templates/shop/index.html index 643f03e5..55b0bae9 100644 --- a/shop/templates/shop/index.html +++ b/shop/templates/shop/index.html @@ -1,26 +1,111 @@ + + Товары + +
+
+
+ +
+
+
-

Список

- - - - - - - {% for p in products %} - - - - +
+

Наименование

Цена

{{ p.name }}

{{ p.price }}

Купить

+ + + + + - {% endfor %} -

Наименование

Цена

Количество

+ {% for p in products %} + +

{{ p.name }}

+

{{ p.price }}

+

{{ p.quantity }}

+

Купить

+ + {% endfor %} + +
diff --git a/shop/templates/shop/purchase_form.html b/shop/templates/shop/purchase_form.html index 3baf70f5..055a6e0c 100644 --- a/shop/templates/shop/purchase_form.html +++ b/shop/templates/shop/purchase_form.html @@ -3,26 +3,107 @@ Покупка + +
+
+
+ +
+
+
-

Покупка

-
{% csrf_token %} - - - - - - - - - - - -

Введите свое имя

Введите адрес доставки:

- -
-
+
+
{% csrf_token %} + + + + + + + + + + + +

Введите свое имя

Введите адрес доставки:

+ +
+
+
diff --git a/shop/tests/test_models.py b/shop/tests/test_models.py index 65a4bffc..f68bc8c1 100644 --- a/shop/tests/test_models.py +++ b/shop/tests/test_models.py @@ -4,23 +4,27 @@ class ProductTestCase(TestCase): def setUp(self): - Product.objects.create(name="book", price="740") - Product.objects.create(name="pencil", price="50") + Product.objects.create(name="book", price="740", quantity="3") + Product.objects.create(name="pencil", price="50", quantity="1") def test_correctness_types(self): self.assertIsInstance(Product.objects.get(name="book").name, str) self.assertIsInstance(Product.objects.get(name="book").price, int) + self.assertIsInstance(Product.objects.get(name="book").quantity, int) self.assertIsInstance(Product.objects.get(name="pencil").name, str) - self.assertIsInstance(Product.objects.get(name="pencil").price, int) + self.assertIsInstance(Product.objects.get(name="pencil").price, int) + self.assertIsInstance(Product.objects.get(name="pencil").quantity, int) def test_correctness_data(self): self.assertTrue(Product.objects.get(name="book").price == 740) + self.assertTrue(Product.objects.get(name="book").quantity > 0) self.assertTrue(Product.objects.get(name="pencil").price == 50) + self.assertTrue(Product.objects.get(name="pencil").quantity > 0) class PurchaseTestCase(TestCase): def setUp(self): - self.product_book = Product.objects.create(name="book", price="740") + self.product_book = Product.objects.create(name="book", price="740", quantity="3") self.datetime = datetime.now() Purchase.objects.create(product=self.product_book, person="Ivanov", diff --git a/shop/views.py b/shop/views.py index feb7eb60..4b6f6226 100644 --- a/shop/views.py +++ b/shop/views.py @@ -1,21 +1,21 @@ from django.shortcuts import render from django.http import HttpResponse from django.views.generic.edit import CreateView - +from django.db.models import F from .models import Product, Purchase # Create your views here. def index(request): - products = Product.objects.all() + products = Product.objects.exclude(quantity = 0) context = {'products': products} return render(request, 'shop/index.html', context) - class PurchaseCreate(CreateView): model = Purchase fields = ['product', 'person', 'address'] def form_valid(self, form): self.object = form.save() + product_id = int(''.join(filter(str.isdigit, str(self.object.product)))) + products = Product.objects.filter(pk=product_id).update(quantity=F('quantity') - 1) return HttpResponse(f'Спасибо за покупку, {self.object.person}!') -