victor_usachev
@victor_usachev
Python Dev

Как реализовать на tastypie такую логику?

Пытаюсь реализовать на 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, чтобы реализовать это. Третий день ищу в документации "то, не зная что".
  • Вопрос задан
  • 556 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы