Лекция #5. Введение в язык программирования Python 3Яковенко КириллWeb-программирование
Лекция #5. Введение в язык программирования Python 3
Цикл лекций читается в Омском государственном университете им. Ф.М.Достоевского на факультете компьютерных наук.
Лектор: Яковенко Кирилл Сергеевич.
2014-08-02 01 Егор Непомнящих. jWidget - очередной MV*-фреймворкОмские ИТ-субботникиАвтор фреймворка jWidget рассказывает о причинах его появления и внутренней организации.
Лекция #7. Django ORMЯковенко КириллWeb-программирование
Лекция #7. Django ORM
Цикл лекций читается в Омском государственном университете им. Ф.М.Достоевского на факультете компьютерных наук.
Лектор: Яковенко Кирилл Сергеевич.
Эффективное программирование на NodeJSYura BogdanovДоклад рассматривает тонкости nodejs, а так же преимущества Evented I/O для серверных приложений. Будет предоставлен ряд рекоммендаций по правильному построению архитектуры, модульности, масштабированию, дизайну кода. Краткое введение в технологию программирования "волокнами" (fibers) и ряд других эффективных практик.
Илья Шаляпин, Евгений Генералов: Разработка через тестирование в Python и Djn...it-peopleБольшинство примеров тестов в книгах, семинарах и презентациях упрощены настолько, что их невозможно применить в реальных проектах. Из-за такого упрощения, сначала получаешь заряд мотивации, но столкнувшись с суровой действительностью быстро бросаешь написание тестов. Мы решили исправить этот пробел, показав тестирование на реальных примерах из нашей практики. Мы расскажем о тестировании баз данных, сетевых взаимодействий и веб-форм. Также расскажем об инструментах, которые мы используем для тестирования.
2014-08-02 01 Егор Непомнящих. jWidget - очередной MV*-фреймворкОмские ИТ-субботникиАвтор фреймворка jWidget рассказывает о причинах его появления и внутренней организации.
Лекция #7. Django ORMЯковенко КириллWeb-программирование
Лекция #7. Django ORM
Цикл лекций читается в Омском государственном университете им. Ф.М.Достоевского на факультете компьютерных наук.
Лектор: Яковенко Кирилл Сергеевич.
Эффективное программирование на NodeJSYura BogdanovДоклад рассматривает тонкости nodejs, а так же преимущества Evented I/O для серверных приложений. Будет предоставлен ряд рекоммендаций по правильному построению архитектуры, модульности, масштабированию, дизайну кода. Краткое введение в технологию программирования "волокнами" (fibers) и ряд других эффективных практик.
Илья Шаляпин, Евгений Генералов: Разработка через тестирование в Python и Djn...it-peopleБольшинство примеров тестов в книгах, семинарах и презентациях упрощены настолько, что их невозможно применить в реальных проектах. Из-за такого упрощения, сначала получаешь заряд мотивации, но столкнувшись с суровой действительностью быстро бросаешь написание тестов. Мы решили исправить этот пробел, показав тестирование на реальных примерах из нашей практики. Мы расскажем о тестировании баз данных, сетевых взаимодействий и веб-форм. Также расскажем об инструментах, которые мы используем для тестирования.
WebCamp: Developer Day: Parse'им бэкенд - Аким ХалиловGeeksLab OdessaРarse'им бэкенд
Аким Халилов
Вы хотите выучить Backbone? Хотите просто писать клиентский код, не думая о сервере и о том, как все обрабатывать, хранить, бэкапить? Выход есть – храните с помощью Parse. Parse – платформа, которая предоставляет возможность хранения данных без забот о сервере. Хранилище данных, соц. сети, push-notification, cloud code. Что такое Parse и что он умеет, о библиотеке для использования:
- знакомство с JS API и примеры использования;
- начинаем кодить: stub-проект;
- кодим фичи: CRUD + плюшки;
- хостим.
Организация работы с API на Vue.js, Виталий КопачёвMail.ru GroupВ процессе работы из проекта в проект я тащу свой «велосипед», постоянного его подтачиваю или модифицирую под конкретные нужды. Хотел бы рассказать о нем, его плюсах и минусах. Кроме этого, поговорим о том, какие «велосипеды» для работы с API существуют.
12 - Web-технологии. Django моделиRoman Brovko1. Создание и изменение объектов
2. Загрузка данных из базы
3. QuerySet
4. ModelManagers
5. Расширение ModelManagers
6. Миграции баз данных
10 - Web-технологии. MVC фреймворки (продолжение)Roman Brovko1. Контроллеры в Django
2. Объекты HttpRequest и HttpResponse
3. Получение GET и POST параметров
4. Работа с HTTP заголовками в Django
5. Декораторы
6. Шаблонизация в Django
7. Наследование шаблонов
8. Context processors
Тестирование и DjangoMoscowDjangoКогда тестировать, что тестировать, как тестировать, Как ускорить тесты и упростить их написание. Отказываемся от классических фикстур в пользу динамически создаваемых моделей.
TDD или как я стараюсь писать кодMoscowDjangoВ докладе я расскажу о том как я вижу и применяю TDD, почему мне это нравится и почему я хочу, чтобы это нравилось другим. Все это на примере какого-нибудь мини-приложения на базе Django.
Cyclone + Eventsource (realtime push-сообщения)MoscowDjangoCyclone is a realtime push messaging library for Go that can be used with Server Sent Events (SSE) to provide asynchronous non-blocking broadcasts of server-sent events over HTTP. Cyclone-SSE is an open source project that combines Cyclone with SSE to provide a polyfill for broadcasting SSE messages using long-polling, HTTP, Redis, or AMQP. It aims to handle DOM exceptions and work around limitations of Nginx. An example shows logging message data received from an EventSource to the browser console.
Class Based Generic Views в DjangoMoscowDjangoThe document discusses Django's class-based generic views. It provides an overview of common class-based views like TemplateView, ListView, DetailView, CreateView, UpdateView, and DeleteView. It also compares implementing views as functions versus classes, noting that classes provide code reuse through inheritance and method overriding.
2. ЧТО ЭТО И ЗАЧЕМ?
Расширяемость – возможность добавления
функционала при помощи
API, предоставляемого приложением
Простой пример
AUTHENTICATION_BACKENDS в contrib.auth
Решает проблемы:
Повторное использование в различных условиях
Изменение логики приложения, без
вмешательства в основной код
3. DJANGO - РАСШИРЯЕМОЕ ПРИЛОЖЕНИЕ :)
Любое приложение для django - по сути
расширение функционала при помощи API.
Благодаря этому, в django есть все необходимые
инструменты и множество примеров
django.utils.importlib.import_module
django.utils.module_loading.module_has_submodule
4. ПРАКТИКУМ
Представим, что нам надо разработать
платформу Интернет-магазина
# catalog.models
class Category(models.Model):
title = models.CharField(max_length=32)
slug = models.SlugField(max_length=32 , unique=True)
class Product(models.Model):
title = models.CharField(max_length=32)
slug = models.SlugField(max_length=32, unique=True)
category = models.ForeignKey("Category")
price = models.DecimalField(max_digits=10, decimal_places=2)
6. ПРАКТИКУМ
А что если нам понадобятся дополнительные
услуги по заказам?
Доставка – обязательно понадобиться
Упаковка
Еще что-нибудь
Причем, эти услуги могут быть разными, для
разных ИМ на базе нашей платформы
И мы даже не можем предсказать, какие именно
7. ОБОБЩИМ ТРЕБОВАНИЯ К УСЛУГЕ
Название
Описание
Цена – может статичная, или зависеть от заказа
Статус выполнения
Дополнительная информация от клиента
8. КАК НАМ ВСЕ ЭТО ОРГАНИЗОВАТЬ?
Услуга Бэкенд
Заказ Услуга Диспетчер Бэкенд
Услуга Бэкенд
9. ПРИВЯЗКА К ЗАКАЗУ - МОДЕЛЬ
#shop.models
class OrderService(models.Model):
order = models.ForeignKey("Order")
service = models.ForeignKey("Service")
status = models.CharField(max_length=32, blank=True, default="")
data = models.TextField() #Мы будем хранить данные в JSON
# Можно хранить сервисы в базе
class Service(models.Model):
title = models.CharField(max_length=32)
description = models.TextField()
base_price = models.DecimalField(max_digits=10, decimal_places=2)
backend = models.CharField(max_length=32)
active = models.BooleanField(default=False)
10. ПРИВЯЗКА К ЗАКАЗУ - МОДЕЛЬ
# А можно и не хранить
class OrderService(models.Model):
order = models.ForeignKey("Order")
backend = models.CharField(max_length=32)
status = models.CharField(max_length=32, blank=True, default="")
data = models.TextField() #Мы будем хранить данные в JSON
11. САМОЕ ИНТЕРЕСНОЕ
Итак, нам осталось сделать базовый класс для
бэкенда и диспетчер
Какой функционал нам понадобиться?
Вычисление цены
Получение, сохранение и обработка
дополнительной информации
Получение списка доступных статусов
Реакция на смену статусов
13. И ДИСПЕТЧЕР
#Построение списка бэкендов
#Вариант первый – мы заранее знаем список плагинов
#settings
settings.SHOP_SERVICES_BACKENDS = {
"simple_delivery" : "shop.services.delivery.SimpleDelivery"
}
#shop.utils
def get_backends(init=False, initial_data=None):
backends = []
for backend_key in settings.SHOP_SERVICES_BACKENDS:
try:
path = settings.SHOP_SERVICES_BACKENDS[backend_key]
i = path.rfind('.')
module, attr = path[:i], path[i+1:]
mod = import_module()
cls = getattr(mod, attr)
if init:
backends.append(cls(data=initial_data))
else:
backends.append(cls)
except ImportError:
continue
return backends
14. И ДИСПЕТЧЕР
#Вариант второй – загрузка только тех модулей, которые указаны в БД
def get_backends(init=False, initial_data=None):
for service in Service.objects.all():
#Принцип тот же что и в первом варианте
…
15. И ДИСПЕТЧЕР
#Вариант третий – инспектирование модуля для поиска плагинов
import inspect
import pkgutil
from django.utils.importlib import import_module
from shop import services
def get_backends(init=False,pkgutil.iter_modules(path=None, prefix='')
initial_data=None, as_list=True):
if as_list: Возвращает кортеж
backends = [] import_module(name, package=None)
else:
(module_loader, name, ispkg) для всех
backends = {}
Импортирует модуль. Удобство в том, что если
подмодулей
передать имя начинающееся с точки
inspect.getmembers(object[, predicate])
for mod in pkgutil.iter_modules(services.__path__):
Возвращаетто поисквсех членов объекта
".name", список для импорта будет
module = import_module('.{0}'.format(mod[1]), 'shop.services')
производиться не по sys.path, а только в
predicate = lambda x: inspect.isclass(x) and issubclass(x, services.BaseService) and not
(аттрибуты, функции, классы и т.д.). Если
x == services.BaseService
указанном во втором аргументе пакете.
for name, backend in inspect.getmembers(module,аргумента передать
качестве второго predicate):
if init: функцию-ограничитель, то inspect.getmembers
value = backend(data=initial_data) те члены, для которых predicate
вернет только
else:
value = backend вернет True
if as_list:
backends.append(value)
else:
backends.update({backend.keyword: value})
return backends
16. И ДИСПЕТЧЕР
#Получение класса бэкенда по имени
#Если бэкенда нет, мы можем или возвращать None
def get_backend(name, init=False, initial_data=None):
return get_backends(init, initial_data).get(name)
#Или же
def get_backend(name, init=False, initial_data=None):
backend = get_backends(init, initial_data) .get(name)
if not backend:
raise ImproperlyConfigured(u"There is no service backend named `{0}`".format(name))
17. ПОПРОБУЕМ СОБРАТЬ ЭТО ВСЕ
class ProcessOrderView(View):
def get(self, *args, **kwargs):
context = {
"order_form": OrderForm(),
"services": get_backends(init=True)
}
return self.render_to_response(context)
def get_services(self):
if not hasattr(self, "_submitted_services"):
services = []
for service_name in self.request.POST.getlist("service"):
service = get_backend(service_name, init=True, initial_data=self.request.POST)
services.append(service)
self._submitted_services = services
return self._submitted_services
def all_services_valid(self):
valid = True
for service in self.get_services():
if not service.get_form().is_valid():
valid = False
return valid
18. ПОПРОБУЕМ СОБРАТЬ ЭТО ВСЕ
def post(self, *args, **kwargs):
order_form = OrderForm(self.request.POST)
valid = True
if order_form.is_valid() and self.all_services_valid():
order = order_form.save()
for service in self.get_services():
form_data = json.dumps(service.get_form().cleaned_data)
OrderService.objects.create(order=order, backend=service.keyword, data=form_data)
return HttpResponseRedirect("/shop/success/")
else:
valid = False
if not valid:
services = self.get_filled_services()
context = {
"order_form": order_form,
"services": services
}
return self.render_to_response(context)
def get_filled_services(self):
services = []
for service in get_backends():
if service.keyword in self.request.POST.getlist("service"):
service.checked = True
services.append(service(data=self.request.POST))
else:
service.checked = False
services.append(service)
return services
19. ПОПРОБУЕМ СОБРАТЬ ЭТО ВСЕ
#Шаблон
#templates/shop/order_process.html
{% extends "shop.html" %}
{% block content %}
<form method="POST">{% csrf_token %}
{{ order_form.as_p }}
{% for service in services %}
<div class="service {{ service.keyword }}">
<input type="checkbox" name="service" value="{{ service.keyword }}"{% if
service.checked %} checked{% endif %}><label>{{ service.get_title }}</label>
<div><small>{{ service.get_description }}</small></div>
{% if service.has_form %}
{{ service.get_form.as_p }}
{% endif %}
</div>
{% endfor %}
<input type="submit">
</form>{% endblock %}
23. А ТЕПЕРЬ ЕЩЕ ОДНУ
class SingingCourier(BaseService):
has_form = False
keyword = "singing_courier"
def get_title(self):
return u"Поющий курьер"
def get_description(self):
return u"Курьер споет вам любую песню на ваш выбор"