Пытаюсь реализовать на Python/Django и Tastypie REST API , для примера взят обычный чек.
Дано:
У чека есть:
- номер чека (уникальное значение),
- дата создания чека,
- дата последней модификации чека (заполняется приложением),
- полная стоимость товаров,
- скидка (заполняется приложением),
- сумма к оплате (заполняется приложением),
- статус (по умолчанию "Обработан").
Веб-сервис по запросу POST на коллекцию должен:
- создать новый чек, если номер чека в присланных данных отсутствует; в ином случае попытаться обновить уже существующий чек, чей номер совпадает с присланным,
- в случае создания нового чека создать номер чека в формате "RCPT-<уникальный номер>",
- вычислить размер скидки как 3% от полной стоимости товаров, и заполнить полученным значением поле "скидка",
- вычислить сумму к оплате, как разность между значениями полной стоимости товаров и скидки; получившимся значением заполнить поле "сумма к оплате",
- в случае создания нового чека, и если дата/время создания чека в присланных данных отсутствует, заполнить текущей датой/временем поле "дата создания чека"; если дата создания чека в присланных данных имеется, сохранить присланную дату,
- в случае обновления существующего чека, сохранить исходную дату создания чека вне зависимости от присланных данных,
- заполнить поле "дата последней модификации чека" текущей датой/временем, проигнорировав любые присланные данные,
- заполнить поле статус значением по-умолчанию "Обработан".
Веб-сервис по запросу GET на коллекцию должен вернуть все чеки со статусом "Обработан". Чеки с иными статусами должны быть скрыты.
Веб-сервис по запросу DELETE на экземпляр коллекции, должен изменить статус выбранного чека на статус "Отменен".
Все прочие запросы веб-сервис должен игнорировать.
Написал:
retail/models.py:
import uuid
from django.db import models
from django.utils import timezone
class Receipt(models.Model):
''' Retail receipt '''
number = models.CharField(max_length=20, unique=True, editable=False)
full_price = models.FloatField()
discount = models.FloatField()
final_amount = models.FloatField()
status = models.CharField(max_length=20, default='Обработан')
created = models.DateTimeField() # editable=True
modified = models.DateTimeField()
def __init__(self, *args, **kwargs):
super(Receipt, self).__init__(*args, **kwargs)
# "RCPT-<уникальный номер>"
self.number = 'RCPT-' + uuid.uuid4().hex
def save(self, *args, **kwargs):
''' On save, update timestamps '''
self.modified = timezone.now()
if not self.id:
self.created = self.modified
return super(Receipt, self).save(*args, **kwargs)
retail/api.py:
from tastypie.resources import ModelResource
from tastypie.authorization import Authorization
from retail.models import Receipt
class ReceiptResource(ModelResource):
class Meta:
queryset = Receipt.objects.all()
list_allowed_methods = ['get', 'post', 'delete']
resource_name = 'receipt'
authorization = Authorization()
# filtering = {
# 'status': ['Обработан'],
# }
def get_object_list(self, request):
# .filter(status='Обработан') - это ничего не дало
return super(ReceiptResource, self).get_object_list(request).filter(status='Обработан')
myapp/urls.py:
from django.conf.urls import url, include
from django.contrib import admin
from retail.api import ReceiptResource
receipt_resource = ReceiptResource()
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/', include(receipt_resource.urls)),
]
Работа с датами вроде отвечает требованиям, номер тоже, но фильтрация по статусу, выполнение какой-либо логики при POST/GET/DELETE запросах - как это сделать?
Прошу подсказать, что мне нужно в Tastypie, чтобы реализовать это. Третий день ищу в документации "то, не зная что".