From 2b88ed6122ee852512cb960b19ee2db34ec6218b Mon Sep 17 00:00:00 2001 From: VladislavOstapov Date: Wed, 26 Apr 2023 01:42:51 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=B0=20por?= =?UTF-8?q?tfolio.edit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/api_methods.py | 83 +++++++++++++++++++++++++++++++++++++--------- api/api_params.py | 5 ++- 2 files changed, 71 insertions(+), 17 deletions(-) diff --git a/api/api_methods.py b/api/api_methods.py index 3d15928..2ba09dc 100755 --- a/api/api_methods.py +++ b/api/api_methods.py @@ -741,8 +741,26 @@ class ApiMedia: class ApiPortfolio: - # portfel.get(user_id=None, portfel_id=None, count=20, offset=0, order_by={date,-date, .... }) - # portfel.create(поля портфолио) + __related_select = [ + 'account', 'account__accountavatar', 'account__accountavatar__photo', + 'account__accountavatar__profile_background', + 'account__executoraccount' + ] + + @staticmethod + def __portfolio_as_json(p: Portfolio): + return { + "owner": ApiAccount.make_user_json(p.account), + "id": p.id, + "title": p.title, + "actual_date": int(time.mktime(p.actual_date.timetuple())), + "publish_date": int(time.mktime(p.publish_date.timetuple())), + "actual_price": float(p.actual_price), + "square": float(p.square), + "photos": [random.randint(4, 28) for _ in range(random.randint(1, 5))], + "attributes": p.attributes + } + # portfel.delete(portfel_id) @staticmethod @api_method("portfolio.create", @@ -773,6 +791,51 @@ class ApiPortfolio: traceback.print_exc() raise Exception(API_ERROR_INTERNAL_ERROR) + @staticmethod + @api_method("portfolio.edit", + doc="Создания объекта портфолио", + params=[ + ApiParamAccessToken(), + ApiParamInt(name="portfolio_id", description="ID портфолио", required=True), + ApiParamStr(name="title", min_length=5, max_length=200, required=False, default=None, + description="Название выполненного заказа, 5-200 символов"), + # ApiParamInt(name="date", required=False, default=None, + # description="Дата в формате UNIX time, потом будет нормальный объект даты," + # "если не передать то будет вставлена текущая дата"), + ApiParamFloat(name="price", description="Цена заказа, актуальная на момент выполнения", + required=False, default=None), + ApiParamFloat(name='square', value_max=99999.99, value_min=1.0, required=False, default=None, + description='Площадь в м²'), + ApiParamTags(name='tags', tags=Portfolio.TAGS_NAMES, required=False, default=None) + ], returns="id созданного объекта") + async def edit(access_token, portfolio_id, title, price, square, tags): + # проверка на то, существует ли портфолио + if await Portfolio.objects.filter(pk=portfolio_id).acount() != 1: + raise Exception(API_ERROR_NOT_FOUND, f"portfolio with id {portfolio_id} not found") + + # проверка владельца + p_filtered = Portfolio.objects.filter(pk=portfolio_id, account=access_token.user) + if await p_filtered.acount() != 1: + raise Exception(API_ERROR_ACCESS_DENIED, "you must be owner") + + try: + edit_fields = {} + if title is not None: + edit_fields["title"] = title + if price is not None: + edit_fields["price"] = price + if square is not None: + edit_fields["square"] = square + if tags is not None: + edit_fields["attributes"] = {"tags": tags} + + await p_filtered.aupdate(**edit_fields) + p = await p_filtered.select_related(*ApiPortfolio.__related_select).afirst() + return api_make_response(ApiPortfolio.__portfolio_as_json(p)) + except Exception: + traceback.print_exc() + raise Exception(API_ERROR_INTERNAL_ERROR) + @staticmethod @api_method("portfolio.get", doc="Получение портфолио или ленты портфолио", @@ -790,9 +853,7 @@ class ApiPortfolio: ], returns="") async def get(access_token, owner_id, portfolio_id, tags, count, offset): res = Portfolio.objects.order_by('actual_date') - res = res.select_related('account', 'account__accountavatar', 'account__accountavatar__photo', - 'account__accountavatar__profile_background', - 'account__executoraccount') + res = res.select_related(*ApiPortfolio.__related_select) if owner_id is not None: res = res.filter(account_id=owner_id) @@ -806,17 +867,7 @@ class ApiPortfolio: res = res[offset:offset + count] # выполняем fetch - objects = [{ - "owner": ApiAccount.make_user_json(item.account), - "id": item.id, - "title": item.title, - "actual_date": int(time.mktime(item.actual_date.timetuple())), - "publish_date": int(time.mktime(item.publish_date.timetuple())), - "actual_price": float(item.actual_price), - "square": float(item.square), - "photos": [random.randint(4, 28) for _ in range(random.randint(1, 5))], - "attributes": item.attributes - } async for item in res] + objects = [ApiPortfolio.__portfolio_as_json(item) async for item in res] return api_make_response(objects) diff --git a/api/api_params.py b/api/api_params.py index 65bf855..1fceef3 100755 --- a/api/api_params.py +++ b/api/api_params.py @@ -300,7 +300,8 @@ class ApiParamEmail(ApiParamStr): class ApiParamTags(ApiParamStr): def __init__(self, tags: list[list[str, str] | tuple[str, str]], name="tags", default=None, description="Один или несколько тегов из списка: {tags}" - " Теги перечисляются через запятую, без кавычек", **kwargs): + " Теги перечисляются через запятую, без кавычек. " + "Пустой список можно передать ключевым словом '_empty_'.", **kwargs): super().__init__(name=name, description=description, regex="^[\\w\\_]+(,[\\w\\_]+)*$", default=None, **kwargs) self.tags = tags @@ -310,6 +311,8 @@ class ApiParamTags(ApiParamStr): def validate(self, value): items = super(ApiParamTags, self).validate(value) if items is not None: + if items == "_empty_": + return [] items = value.split(',') # проверка того, что параметры входят в список for i in items: