Skip to content

Commit 8d26f03

Browse files
feat(mock_api): add version field to avoid update by older data (#201)
Co-authored-by: rikasai233 <[email protected]>
1 parent 5c52e0a commit 8d26f03

File tree

5 files changed

+37
-0
lines changed

5 files changed

+37
-0
lines changed

mock/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ class MockAPI(BaseTable):
6464
api_id = models.CharField(max_length=32, default=lambda: uuid.uuid4().hex, unique=True)
6565
enabled = models.BooleanField(default=True)
6666

67+
# 添加version字段用于乐观锁控制
68+
version = models.IntegerField(default=1) # 新增版本字段,默认值为1
69+
6770
# TODO 改成many to many
6871
# followers: list = models.JSONField(null=True, blank=True, default=[], verbose_name="关注者")
6972

mock/serializers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class Meta:
2525
"request_method",
2626
"request_body",
2727
"response_text",
28+
"version",
2829
"is_active",
2930
"api_id",
3031
"api_desc",

mock/views.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,37 @@ class MockAPIViewset(viewsets.ModelViewSet):
5353
filter_backends = [DjangoFilterBackend]
5454
filterset_class = MockAPIFilter
5555

56+
def update(self, request, *args, **kwargs):
57+
partial = kwargs.pop('partial', False)
58+
instance = self.get_object()
59+
60+
# 获取传入的版本号
61+
incoming_version = request.data.get('version')
62+
63+
# 如果数据库中的版本号比传入的版本号更大,阻止更新并返回错误
64+
if incoming_version is not None and instance.version > int(incoming_version):
65+
return Response({
66+
'status': 'error',
67+
'message': 'There is a newer version of this API already saved.'
68+
}, status=status.HTTP_409_CONFLICT)
69+
70+
serializer = self.get_serializer(instance, data=request.data, partial=partial)
71+
serializer.is_valid(raise_exception=True)
72+
73+
# 序列化器保存了实例,但我们还没有更新版本号
74+
self.perform_update(serializer)
75+
76+
# 保存成功后,递增版本号并更新实例
77+
instance.version += 1
78+
instance.save(update_fields=['version']) # 只更新版本字段
79+
80+
if getattr(instance, '_prefetched_objects_cache', None):
81+
# If 'prefetch_related' has been applied to a queryset, we need to
82+
# forcibly invalidate the prefetch cache on the instance.
83+
instance._prefetched_objects_cache = {}
84+
85+
return Response(serializer.data)
86+
5687
class RequestObject:
5788
def __init__(self, request):
5889
self.method: str = request.method

web/src/pages/mock_server/mock_api/index.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ def execute(req, resp):
259259
260260
],
261261
paginationSize: 10,
262+
operationButtonType: 'button',
262263
searchForm: [
263264
{
264265
type: 'input',

web/src/pages/mock_server/mock_project/index.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export default {
1010
dataPath: "results",
1111
totalPath: "count",
1212
paginationSize: 10,
13+
operationButtonType: 'button',
1314
canDelete: () => false,
1415
form: [
1516
{

0 commit comments

Comments
 (0)