Skip to content

Commit c79da52

Browse files
committed
feat(core): update pydantic to v2, django-ninja to v1
1 parent 19376d6 commit c79da52

File tree

8 files changed

+44
-41
lines changed

8 files changed

+44
-41
lines changed

core/router.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Any, List, Optional, Type, TypeVar, Union
22

3-
from core.schemas import DictId, PageFilter, PageSchema, StandResponse
3+
4+
from core.schemas import DictId, PageFilter, PageSchema, StandResponse, OptionalDictResponseType
45
from core.service import GenericCURD
56
from ninja import Body, Query, Router, Schema
67
from ninja.constants import NOT_SET_TYPE
@@ -41,18 +42,19 @@ def create_obj(request, payload: self.in_schema):
4142
f"{self.path}/{{id}}", response=StandResponse[Union[self.out_schema, None]]
4243
)
4344
def get_obj(request, id: int):
44-
return self.service_impl.get_obj(id)
45+
obj = self.service_impl.get_obj(id)
46+
return StandResponse[Union[self.out_schema, None]](data=obj.data)
4547

4648
# get a list of objs
4749
@self.get(self.path, response=StandResponse[PageSchema[self.out_schema]])
4850
def list_obj(request, filters: self.filters_class = Query(...)):
4951
objs = self.service_impl.list_obj(filters, self.out_schema)
50-
return StandResponse(data=objs)
52+
return StandResponse[PageSchema[self.out_schema]](data=objs)
5153

5254
# full update obj
5355
@self.put(
5456
f"{self.path}/{{id}}",
55-
response=StandResponse[Union[DictId, dict]],
57+
response=OptionalDictResponseType,
5658
description="full obj update",
5759
)
5860
def update_obj(request, id: int, payload: self.in_schema):
@@ -63,7 +65,7 @@ def update_obj(request, id: int, payload: self.in_schema):
6365
# partial update obj
6466
@self.patch(
6567
f"{self.path}/{{id}}",
66-
response=StandResponse[Union[DictId, None]],
68+
response=OptionalDictResponseType,
6769
description="partial obj update",
6870
)
6971
def partial_update_obj(request, id: int, payload: dict = Body(...)):

core/schemas.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
from enum import IntEnum
2-
from typing import TypeVar, Generic, List, Optional
1+
from typing import TypeVar, Generic, List, Optional, Union
32
from ninja import Schema
4-
from pydantic import conint, validator, BaseModel, Field
5-
from pydantic.generics import GenericModel
3+
from pydantic import conint, BaseModel, Field, field_validator
64

75

86
class ErrorMsg(BaseModel):
@@ -13,15 +11,18 @@ class ErrorMsg(BaseModel):
1311
GenericResultsType = TypeVar("GenericResultsType")
1412

1513

16-
class StandResponse(ErrorMsg, GenericModel, Generic[GenericResultsType]):
14+
class StandResponse(ErrorMsg, Generic[GenericResultsType]):
1715
data: GenericResultsType
1816

1917

2018
class DictId(BaseModel):
2119
id: conint(ge=-1)
2220

2321

24-
class PageSchema(GenericModel, Generic[GenericResultsType]):
22+
OptionalDictResponseType = StandResponse[Union[Optional[DictId], dict]]
23+
24+
25+
class PageSchema(BaseModel, Generic[GenericResultsType]):
2526
total: int
2627
page_size: int
2728
page_index: int
@@ -33,7 +34,7 @@ class PageFilter(Schema):
3334
page_size: conint(ge=1, le=100) = 10
3435
ordering: str = Field("", alias="ordering", description="排序字段,多个时用,分割")
3536

36-
@validator("page_index")
37+
@field_validator("page_index")
3738
def page_index_check(cls, page_index):
3839
if page_index <= 1:
3940
return 1
@@ -43,17 +44,17 @@ def dict(
4344
self,
4445
*,
4546
exclude_none=True,
46-
exclude={"page_index", "page_size", "ordering"},
47+
exclude=None,
4748
by_alias: bool = False,
48-
skip_defaults: bool = None,
4949
exclude_unset: bool = False,
5050
exclude_defaults: bool = False,
5151
) -> "DictStrAny":
52+
if exclude is None:
53+
exclude = {"page_index", "page_size", "ordering"}
5254
return super().dict(
5355
exclude_none=exclude_none,
5456
exclude=exclude,
5557
by_alias=by_alias,
56-
skip_defaults=skip_defaults,
5758
exclude_unset=exclude_unset,
5859
exclude_defaults=exclude_defaults,
5960
)

core/service.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import uuid
22
from abc import ABC, abstractmethod
3-
from typing import Any, Union
3+
from typing import Any, Union, Optional
44

55
from core import cache, response
66
from core.model import CoreModelSoftDelete
7-
from core.schemas import DictId, PageFilter, PageSchema, StandResponse
7+
from core.schemas import DictId, PageFilter, PageSchema, StandResponse, OptionalDictResponseType
88
from django.db.models import Model
99
from django.http import Http404
1010
from django.shortcuts import get_object_or_404
@@ -83,7 +83,7 @@ def list_obj(self, page_filter: PageFilter, page_schema: PageSchema) -> PageSche
8383

8484
def update_obj(
8585
self, id: int, payload, user_email
86-
) -> StandResponse[Union[DictId, dict]]:
86+
) -> OptionalDictResponseType:
8787
return model_opertion.update(
8888
updater=user_email, model=self.model, payload=payload, obj_id=id
8989
)
@@ -139,10 +139,10 @@ def list_obj(self, page_filter: PageFilter, page_schema: PageSchema) -> PageSche
139139

140140
def update_obj(
141141
self, id: int, payload: GenericPayload, user_email: str
142-
) -> StandResponse[Union[DictId, dict]]:
142+
) -> OptionalDictResponseType:
143143
obj = self._get_obj_by_id(id=id)
144144
if obj is None:
145-
return StandResponse[dict](
145+
return OptionalDictResponseType(
146146
message=f"{id=} not exist", success=False, data={}
147147
)
148148
return model_opertion.update_by_obj(
@@ -151,7 +151,7 @@ def update_obj(
151151

152152
def partial_update(
153153
self, id: int, user_email: str, **fields_kv
154-
) -> StandResponse[Union[DictId, dict]]:
154+
) -> OptionalDictResponseType:
155155
obj = self._get_obj_by_id(id=id)
156156
return model_opertion.update_by_obj(updater=user_email, obj=obj, **fields_kv)
157157

core/tests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def test_get_token_fresh_success(self):
3535
data={"refresh": response_data["data"]["refresh"]},
3636
content_type="application/json",
3737
).json()
38-
self.assertEqual(response['data']['refresh'], response_data['data']['refresh'])
38+
self.assertEqual(response['refresh'], response_data['data']['refresh'])
3939

4040
def test_auth_token_failure_wrong_user_and_password(self):
4141
"""Test the failure of authentication token generation.

employee/schemas.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class EmployeeIn(Schema):
1111
first_name: str
1212
last_name: str
1313
department_id: int = None
14-
birthdate: date = None
14+
birthdate: Optional[date] = None
1515

1616

1717
class EmployeeOut(EmployeeIn):
@@ -21,4 +21,4 @@ class EmployeeOut(EmployeeIn):
2121
class EmployeeFilters(PageFilter):
2222
first_name__contains: str = Field(None, alias="first_name")
2323
last_name__contains: str = Field(None, alias="last_name")
24-
department_id: Optional[conint(ge=0)]
24+
department_id: Optional[conint(ge=0)] = None

employee/tests.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@ def test_get_obj(self):
5757
response = self.token_client.get("/employees/1")
5858

5959
self.assertEqual(response.status_code, 200)
60-
self.assertDictContainsSubset(
60+
resp: dict= response.json()["data"]
61+
resp.pop('id')
62+
self.assertDictEqual(
6163
self.employee_in.dict(),
62-
response.json()["data"],
64+
resp,
6365
f"query input obj: {self.employee_in}",
6466
)
6567

requirements.txt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
asgiref
22
dataclasses
3-
Django~=4.2.2
4-
django-ninja
5-
pydantic~=1.10.9
3+
django-ninja==1.3.0
64
pytz
75
sqlparse
86
typing-extensions
@@ -13,6 +11,6 @@ PyMySQL~=1.0.3
1311
django-redis
1412
gevent==22.10.2
1513
gunicorn==20.1.0
16-
django-ninja-jwt==5.2.7
14+
django-ninja-jwt==5.3.4
1715

1816
django-celery-beat==2.6.0

utils/model_opertion.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
import logging
2-
from typing import TypeVar, Union, Any
2+
from typing import TypeVar, Union, Any, Optional
33
import traceback
44

55
from django.core.exceptions import ValidationError
66
from django.shortcuts import get_object_or_404
77
from pydantic import conint
88

9-
from core.schemas import StandResponse, DictId
9+
from core.schemas import StandResponse, DictId, OptionalDictResponseType
1010
from core.model import CoreModel
1111

1212
logger = logging.getLogger(__name__)
1313

1414
GenericPayload = TypeVar("GenericPayload")
1515

1616

17-
def create(creator: str, model: CoreModel, payload: GenericPayload) -> StandResponse[Union[DictId, None]]:
17+
def create(creator: str, model: CoreModel, payload: GenericPayload) -> StandResponse[Optional[DictId]]:
1818
"""创建对象"""
1919
try:
2020
logger.info(f"input: create={model.__name__}, payload={payload.dict()}")
2121
obj = model.objects.create(creator=creator, **payload.dict())
2222
except Exception as e:
2323
logger.error(traceback.format_exc())
24-
return StandResponse(success=False, message=str(e), data=None)
24+
return StandResponse[Optional[DictId]](success=False, message=str(e), data=None)
2525
logger.info(f"create {model.__name__} success, id: {obj.id}")
26-
return StandResponse(data=DictId(id=obj.id))
26+
return StandResponse[Optional[DictId]](data=DictId(id=obj.id))
2727

2828

2929
def create_obj_with_validate_unique(
@@ -46,10 +46,10 @@ def create_obj_with_validate_unique(
4646
raise e
4747

4848
logger.info(f"create {model.__name__} success, id: {obj.id}")
49-
return StandResponse(data=DictId(id=obj.id))
49+
return StandResponse[Union[DictId, dict]](data=DictId(id=obj.id))
5050

5151

52-
def _update(obj, payload: dict, updater: str) -> StandResponse[Union[DictId,None]]:
52+
def _update(obj, payload: dict, updater: str) -> OptionalDictResponseType:
5353
logger.info(f"input: update={obj.__class__.__name__}, payload={payload}")
5454
obj.updater = updater
5555
for attr, value in payload.items():
@@ -58,9 +58,9 @@ def _update(obj, payload: dict, updater: str) -> StandResponse[Union[DictId,None
5858
obj.save()
5959
except Exception as e:
6060
logger.warning(traceback.format_exc())
61-
return StandResponse(success=False, message=str(e), data=None)
61+
return OptionalDictResponseType(success=False, message=str(e), data=None)
6262
logger.info(f"update {obj.__class__.__name__} success, id: {obj.id}")
63-
return StandResponse(data=DictId(id=obj.id))
63+
return OptionalDictResponseType(data=DictId(id=obj.id))
6464

6565

6666
def update(updater: str, model: CoreModel, payload: GenericPayload, obj_id: conint(ge=1)) -> StandResponse[Union[DictId, None]]:
@@ -69,10 +69,10 @@ def update(updater: str, model: CoreModel, payload: GenericPayload, obj_id: coni
6969
return _update(obj=obj, payload=payload.dict(), updater=updater)
7070

7171

72-
def partial_update(updater: str, model: CoreModel, obj_id: conint(ge=1), **kwargs) -> StandResponse[Union[DictId, None]]:
72+
def partial_update(updater: str, model: CoreModel, obj_id: conint(ge=1), **kwargs) -> OptionalDictResponseType:
7373
obj = get_object_or_404(model, id=obj_id)
7474
return _update(obj=obj, payload=kwargs, updater=updater)
7575

7676

77-
def update_by_obj(obj: CoreModel, updater: str, **kwargs) -> StandResponse[Union[DictId, None]]:
77+
def update_by_obj(obj: CoreModel, updater: str, **kwargs) -> OptionalDictResponseType:
7878
return _update(obj=obj, payload=kwargs, updater=updater)

0 commit comments

Comments
 (0)