Add ab-test
This commit is contained in:
parent
9e344b9920
commit
a9c0b7c689
@ -20,3 +20,6 @@ class AuthTokenAdmin(admin.ModelAdmin):
|
|||||||
admin.site.register(AuthToken, AuthTokenAdmin)
|
admin.site.register(AuthToken, AuthTokenAdmin)
|
||||||
|
|
||||||
admin.site.register(GlobalConfig)
|
admin.site.register(GlobalConfig)
|
||||||
|
|
||||||
|
admin.site.register(ABTest)
|
||||||
|
admin.site.register(ABTestSample)
|
||||||
|
|||||||
@ -414,3 +414,24 @@ class FrameLabel(models.Model):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.oss_path
|
return self.oss_path
|
||||||
|
|
||||||
|
class ABTest(models.Model):
|
||||||
|
name = models.CharField(max_length=128, verbose_name="名称", db_index=True, unique=True)
|
||||||
|
description = models.TextField(verbose_name="描述")
|
||||||
|
test_object = models.CharField(max_length=128, verbose_name="实验对象")
|
||||||
|
create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建日期")
|
||||||
|
update_time = models.DateTimeField(auto_now=True, verbose_name="更新日期")
|
||||||
|
enabled = models.BooleanField(default=True, verbose_name="是否启用")
|
||||||
|
spec = models.TextField(verbose_name="实验配置")
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.name} {self.category}"
|
||||||
|
|
||||||
|
class ABTestSample(models.Model):
|
||||||
|
abtest = models.ForeignKey(ABTest, related_name="samples", on_delete=models.CASCADE)
|
||||||
|
data = models.TextField(verbose_name="实验数据")
|
||||||
|
create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建日期")
|
||||||
|
update_time = models.DateTimeField(auto_now=True, verbose_name="更新日期")
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.pk} {self.abtest.name} {self.create_time}"
|
||||||
|
|||||||
@ -467,6 +467,24 @@ class CameraRuleResource(BaseResource):
|
|||||||
schema['fields']['notes']['longtext'] = True
|
schema['fields']['notes']['longtext'] = True
|
||||||
return schema
|
return schema
|
||||||
|
|
||||||
|
class ABTestResource(BaseResource):
|
||||||
|
class Meta:
|
||||||
|
queryset = ABTest.objects.all().order_by('-pk')
|
||||||
|
resource_name = 'ab-test'
|
||||||
|
authorization = BaseAuthorization()
|
||||||
|
serializer = BaseSerializer()
|
||||||
|
|
||||||
|
auth_role = 'admin'
|
||||||
|
|
||||||
|
class ABTestSampleResource(BaseResource):
|
||||||
|
class Meta:
|
||||||
|
queryset = ABTestSample.objects.all().order_by('-pk')
|
||||||
|
resource_name = 'ab-test-sample'
|
||||||
|
authorization = BaseAuthorization()
|
||||||
|
serializer = BaseSerializer()
|
||||||
|
|
||||||
|
auth_role = 'admin'
|
||||||
|
|
||||||
for cls in BaseResource.__subclasses__():
|
for cls in BaseResource.__subclasses__():
|
||||||
v1_api.register(cls())
|
v1_api.register(cls())
|
||||||
|
|
||||||
@ -1887,3 +1905,37 @@ class LabelFrameView(BaseView):
|
|||||||
'ok': True,
|
'ok': True,
|
||||||
'id': fo.id,
|
'id': fo.id,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class ABTestView(BaseView):
|
||||||
|
name = 'ab-test'
|
||||||
|
auth_check = None
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
test_object = request.GET.get('test_object', None)
|
||||||
|
abtest = ABTest.objects.filter(enabled=True)
|
||||||
|
if test_object:
|
||||||
|
abtest = abtest.filter(test_object=test_object)
|
||||||
|
return JsonResponse({
|
||||||
|
'items': [
|
||||||
|
{
|
||||||
|
'name': abtest.name,
|
||||||
|
'test_object': abtest.test_object,
|
||||||
|
'spec': abtest.spec,
|
||||||
|
}
|
||||||
|
for abtest in abtest
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
class ABTestReportView(BaseView):
|
||||||
|
name = 'ab-test-report'
|
||||||
|
auth_check = None
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
name = request.data.get('name')
|
||||||
|
abtest = ABTest.objects.filter(name=name).first()
|
||||||
|
if not abtest:
|
||||||
|
return http404()
|
||||||
|
sample = ABTestSample.objects.create(abtest=abtest, data=json.dumps(request.data.get('data')))
|
||||||
|
return JsonResponse({
|
||||||
|
'ok': True,
|
||||||
|
})
|
||||||
|
|||||||
@ -158,3 +158,43 @@ class APITest(TestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(r.status_code, 200)
|
self.assertEqual(r.status_code, 200)
|
||||||
self.assertIn('status', r.json())
|
self.assertIn('status', r.json())
|
||||||
|
|
||||||
|
def test_abtest(self):
|
||||||
|
r = self.get("/api/v1/ab-test/", admin=True)
|
||||||
|
self.assertEqual(r.status_code, 200)
|
||||||
|
self.assertIn('items', r.json())
|
||||||
|
self.assertEqual(len(r.json()['items']), 0)
|
||||||
|
|
||||||
|
|
||||||
|
spec = """
|
||||||
|
|
||||||
|
"""
|
||||||
|
ABTest.objects.create(name="test", test_object="dummy", spec=spec)
|
||||||
|
r = self.get("/api/v1/ab-test/", admin=True)
|
||||||
|
self.assertEqual(r.status_code, 200)
|
||||||
|
self.assertIn('items', r.json())
|
||||||
|
self.assertEqual(len(r.json()['items']), 1)
|
||||||
|
self.assertEqual(r.json()['items'][0]['name'], "test")
|
||||||
|
self.assertEqual(r.json()['items'][0]['test_object'], "dummy")
|
||||||
|
self.assertEqual(r.json()['items'][0]['spec'], spec)
|
||||||
|
|
||||||
|
r = self.get("/api/v1/ab-test/?test_object=dummy")
|
||||||
|
self.assertEqual(r.status_code, 200)
|
||||||
|
self.assertEqual(len(r.json()['items']), 1)
|
||||||
|
|
||||||
|
r = self.post("/api/v1/ab-test-report/", data={
|
||||||
|
'name': "test",
|
||||||
|
'data': {
|
||||||
|
'foo': "bar",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
self.assertEqual(r.status_code, 200)
|
||||||
|
self.assertIn('ok', r.json())
|
||||||
|
self.assertTrue(r.json()['ok'])
|
||||||
|
|
||||||
|
abts = ABTestSample.objects.filter(abtest__name="test")
|
||||||
|
self.assertEqual(len(abts), 1)
|
||||||
|
self.assertEqual(abts[0].abtest.name, "test")
|
||||||
|
self.assertEqual(abts[0].data, json.dumps({
|
||||||
|
'foo': "bar",
|
||||||
|
}))
|
||||||
Loading…
x
Reference in New Issue
Block a user