Диплом: Создание web-сервисов средствами стека технологий Django+Python3.x+Nginx+Gunicorn+PostgreSQL

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам
32
применительно к различным СУБД и проводят сравнительный анализ
моделей. Главной проблемой ЛП является вопрос, каким образом
отобразить объекты предметной области в абстрактные объекты
модели данных, что бы это отображение не противоречило семантике
предметной области и было по возможности лучшим (эффективным,
удобны и т.д.).
5) Физическое проектирование БД
Полученную на предыдущем этапе абстрактную схему БД
реализовываем с помощью, выбранной СУБД и используемых
программных средств.
При выборе СУБД необходимо учитывать:
1) Тип модели данных, которую поддерживает данная СУБД
2) Характеристики производительности системы
3) Запас функциональных возможностей для дальнейшего развития ИС
4) Степень оснащенности инструментарием для администрирования
5) Удобство и надёжность в эксплуатации
6) Стоимость СУБД и дополнительного ПО
Теперь, когда с принципом создания БД разобрались, можно приступать к
созданию самой БД. Как и было заявлено в план-проекте будет построена
ER-диаграмма, а также описан программный код с помощью которого будут
создаваться таблицы в БД.
ER- диаграмма будет разбита на две части, так как на одном листе не
поместится. На рисунке 3 приведена первая часть диаграммы.
33
Рисунок 3 – ER-диаграмма. Часть 1
Стрелками указываются связи между таблицами, а также указываются поля
по которым осуществляется связь. Часть таблиц создаётся автоматически
программными средствами самого фреймворка Django[20]. Каждой записи
присваивается уникальный id. В первой части представлены таблицы,
связанные с данными пользователя.
На рисунке 4 изображена вторая часть диаграммы. Таблицы в ней
отвечают за товар и корзину покупателя.
34
Рисунок 4 – ER-диаграмма. Часть 2
Теперь рассмотрим программный код[14], с помощью которого будут
создаваться все перечисленные таблицы.
Начнём с таблицы создания нового пользователя.
class RegistrationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
password_check = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = [
'username',
'password',
'password_check',
'first_name',
'last_name',
'email',
]
def __init__(self, *args, **kwargs):
super(RegistrationForm, self).__init__(*args, **kwargs)
self.fields['username'].label = 'Логин'
self.fields['password'].label = 'Пароль'
35
self.fields['password'].help_text = 'Придумайте пароль'
self.fields['password_check'].label = 'Повторите пароль'
self.fields['first_name'].label = 'Имя'
self.fields['last_name'].label = 'Фамилия'
self.fields['email'].label = 'Почта'
self.fields['email'].help_text = 'Пожалуйста, укажите реальный адресс'
def clean(self):
username = self.cleaned_data['username']
password = self.cleaned_data['password']
password_check = self.cleaned_data['password_check']
email = self.cleaned_data['email']
if User.objects.filter(username=username).exists():
raise forms.ValidationError("Пользователь с данным логином уже
зарегистрирован!")
if password != password_check:
raise forms.ValidationError("Ваши пароли не совпадают!")
if User.objects.filter(email=email).exists():
raise forms.ValidationError("Пользователь с данным email зарегистрирован.")
Указанный класс наследуется от forms.ModelForm и создаёт форму
регистрации пользователя, в которой необходимо указать логин, пароль, имя
и фамилию, адрес электронной почты. Он соответствует таблице auth_user.
Так же у этого класса есть два метода. В def __init__ переопределяется метод
инициализации класса таким образом, чтобы при заполнении формы, поля
были подписаны и заполнялись в соответствии с нашими потребностями. Все
остальные таблицы создаются автоматически при помощи библиотеки ORM,
используемой Django[27].
Теперь рассмотрим модели, используемы для создания таблиц,
изображенных на второй части диаграммы.
Для создания таблиц ecomapp_brand и ecomapp_category используется
следующий код:
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField()
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('category_detail', kwargs={'category_slug': self.slug})
Поле slug обозначает короткую ссылку на объект класса, в английском
транслите с заменой пробелов дефисами.
36
class Brand(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
def image_folder(instance, filename):
filename = instance.slug + '.' + filename.split('.')[1]
return "{0}/{1}".format(instance.slug, filename)
Второй метод класса создаёт изображение в папке media с удобочитаемым
именем.
Код для создания таблицы ecomapp_products:
class Products(models.Model):
category = models.ForeignKey(Category)
brand = models.ForeignKey(Brand)
title = models.CharField(max_length=100)
slug = models.SlugField()
description = models.TextField()
image = models.ImageField(upload_to=image_folder)
price = models.DecimalField(max_digits=9, decimal_places=2)
available = models.BooleanField(default=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('product_detail', kwargs={'product_slug': self.slug})
Здесь происходит связь с таблицами категорий и брэндов. Так же задаются
поля названия, slug, описания, изображения товара, цены и наличия.
Код для создания таблицы ecomap_cartitem:
class CartItem(models.Model):
product = models.ForeignKey(Products)
qty = models.PositiveIntegerField(default=1)
item_total = models.DecimalField(max_digits=9, decimal_places=2, default=0.00)
def __str__(self):
return "Cart item for product{0}".format(self.product.title)
Здесь создаётся связь типа «один ко многим» с продуктом, задаётся
количество товара и цена.
Следующий код описывает создание модели корзины.
class Cart(models.Model):
item = models.ManyToManyField(CartItem, blank=True)
cart_total = models.DecimalField(max_digits=9, decimal_places=2, default=0.00)
def __str__(self):
37
return str(self.id)
def add_to_cart(self, product_slug):
cart = self
product = Products.objects.get(slug=product_slug)
new_item, _ = CartItem.objects.get_or_create(product=product, item_total=product.price)
if new_item not in cart.item.all():
cart.item.add(new_item)
cart.save()
def remove_from_cart(self, product_slug):
cart = self
product = Products.objects.get(slug=product_slug)
for cart_item in cart.item.all():
if cart_item.product == product:
cart.item.remove(cart_item)
cart.save()
def change_qty(self, qty, item_id):
cart = self
cart_item = CartItem.objects.get(id=int(item_id))
cart_item.qty = int(qty)
cart_item.item_total = int(qty) * Decimal(cart_item.product.price)
cart_item.save()
new_cart_total = 0.00
for item in cart.item.all():
new_cart_total += float(item.item_total)
cart.cart_total = new_cart_total
cart.save()
В нём создаются лишь два поля – это товар содержащийся в корзине и её
итоговая цена. Так же есть три метода: добавление товара в корзину,
удаление товара из корзины и изменение итоговой цены.
Ну и наконец таблица ecomapp_order. В эту таблицу заносятся все
оформленные заказы пользователя.
class Order(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
items = models.ForeignKey(Cart)
total = models.DecimalField(max_digits=9, decimal_places=2, default=0.00)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
phone = models.CharField(max_length=20)
address = models.CharField(max_length=250)
buying_type = models.CharField(max_length=40, choices=(('Самовывоз', 'Самовывоз'),
('Доставка','Доставка')), default='Самовывоз')
date = models.DateTimeField(auto_now_add=True)
comments = models.TextField()
38
status = models.CharField(max_length=100, choices=ORDER_STATUS_CHOICES,
default=ORDER_STATUS_CHOICES[0][0])
def __str__(self):
return "Заказ №{0}".format(str(self.id))
Здесь создаются поля данных пользователя, так же все товары и их общая
стоимость, статус заказа, способ доставки товара, и автоматически
заполняется поле даты оформления заказа.
Для того, чтобы все эти таблицы были созданы в базе данных,
необходимо после написания кода в файлах программы, прописать две
команды в терминале:
python manage.py makemigrations
python manage.py migrate
Первая команда подготавливает миграции для базы данных, а вторая создаёт
таблицы. Всё это возможно, благодаря встроенной библиотеке ORM.
39
3. Глава. Реализация проекта
3.1 Описание алгоритма работы web-сервиса
Для описания алгоритма работы интернет магазина я использую activity
diagram. На рисунке 5 изображена упомянутая диаграмма.
Рисунок 5 - Activity diagram
Теперь рассмотрим представления, которые позволяют воплотить в жизнь
эту диаграмму[37][38]. Большая часть классов и методов были описаны
ранее, но остались вспомогательные функции, без которых бы ничего не
работало.
Следующая функция позволяет отобразить на главной странице товар,
категории и корзину.
def base_view(request):
try:
cart_id = request.session['cart_id']
cart = Cart.objects.get(id=cart_id)
request.session['total'] = cart.item.count()
except:
cart = Cart()
cart.save()
cart_id = cart.id
40
request.session['cart_id'] = cart_id
cart = Cart.objects.get(id=cart_id)
categories = Category.objects.all()
products = Products.objects.filter(available=True)
context = {
'categories': categories,
'products': products,
'cart': cart,
}
return render(request, 'base.html', context)
Эта функция используется в конфигурации URL.
url(r'^$', base_view, name='base')
Функция add_to_cart добавляет товар в корзину и подсчитывает её общую
стоимость.
def add_to_cart_view(request):
try:
cart_id = request.session['cart_id']
cart = Cart.objects.get(id=cart_id)
request.session['total'] = cart.item.count()
except:
cart = Cart()
cart.save()
cart_id = cart.id
request.session['cart_id'] = cart_id
cart = Cart.objects.get(id=cart_id)
product_slug = request.GET.get('product_slug')
product = Products.objects.get(slug=product_slug)
cart.add_to_cart(product.slug)
new_cart_total = 0.00
for item in cart.item.all():
new_cart_total += float(item.item_total)
cart.cart_total = new_cart_total
cart.save()
return JsonResponse({'cart_total':cart.item.count(), 'cart_total_price': cart.cart_total})
Данная функция не перенаправляет покупателя сразу в корзину, а лишь
возвращает словарь с данными о продукте и ценой.
У пользователя есть возможность изменить количество заказываемого
товара. Для этого была написана функция
def change_item_qty(request):
try:
cart_id = request.session['cart_id']
cart = Cart.objects.get(id=cart_id)
request.session['total'] = cart.item.count()
except:
cart = Cart()
cart.save()
41
cart_id = cart.id
request.session['cart_id'] = cart_id
cart = Cart.objects.get(id=cart_id)
qty = request.GET.get('qty')
item_id = request.GET.get('item_id')
cart.change_qty(qty, item_id)
cart_item = CartItem.objects.get(id=int(item_id))
return JsonResponse(
{'cart_total': cart.item.count(),
'item_total': cart_item.item_total,
'cart_total_price': cart.cart_total})
Так как она используется в самой корзине, то куда либо перенаправлять
пользователя не нужно. Функция возвращает словарь с информации о товаре,
стоимости товара и стоимости корзины.
Функция checkout_view() перенаправляет пользователя на страницу
просмотра предварительного заказа.
def checkout_view(request):
try:
cart_id = request.session['cart_id']
cart = Cart.objects.get(id=cart_id)
request.session['total'] = cart.item.count()
except:
cart = Cart()
cart.save()
cart_id = cart.id
request.session['cart_id'] = cart_id
cart = Cart.objects.get(id=cart_id)
categories = Category.objects.all()
context = {
'cart': cart,
'categories': categories,
}
return render(request, 'checkout.html', context)
Используется в конфигурации URL
url(r'^checkout/$', checkout_view, name='checkout')
Функция order_create_view() перенаправляет пользователя на страницу
оформления заказа.
def order_create_view(request):
try:
cart_id = request.session['cart_id']
cart = Cart.objects.get(id=cart_id)
request.session['total'] = cart.item.count()
except:
cart = Cart()
cart.save()

Смотрите также:

"Автоматизация обработки заявок ООО "Проектно-Строительная Компания"
"Автоматизация процесса аттестации персонала для ООО "Нэт Бай Нэт Холдинг"
"Анализ интернет-активности конкурентов ( на примере конкурентов "Газпром нефть")
"Бухгалтерский учёт и аудит расчётов с подотчётними лицами в организации на примере ООО "ЛОЦ 10""
«Психологическое сопровождение персонала в организации на примере ООО «Крокус»
Cовершенствование деловой оценки персонала в организации (на примере ООО "Даймонд кейтеринг развитие")
PR как средство продвижения организации (на примере ПАО "Тамбовский завод "Комсомолец им. Н.С. Артемова")
PR-коммуникации в сфере общественного питания (на примере кафе-кондитерской «Cream Cheese»)
SMM как средство повышения эффективности работы учреждений социокультурной сферы (на примере Малого театра)
Value-based education: ценности в системе образования и способы их реализации на уроке английского языка. Опыт Европейских стран