我正在使用Django Rest Framework。我有一个现有的数据库(无法对其进行任何更改)。我定义了一个序列化器-没有模型的ReceiptLog,当对ReceiptLog api端点发出post()请求时,应该在TestCaseCommandRun和TestCaseCommandRunResults中创建条目。收据日志在数据库中不存在,我只是将其用作端点来接受组合的有效负载并在基础表中创建条目。 Post()到TestCaseCommandRunResults和TestCaseCommandRun可以独立工作,但是,当我尝试通过ReceiptLog进行发布时,它抛出以下错误
错误回溯:
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.6/contextlib.py" in inner
52. return func(*args, **kwds)
File "/usr/local/lib/python3.6/dist-packages/django/views/decorators/csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/django/views/generic/base.py" in view
69. return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in dispatch
495. response = self.handle_exception(exc)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in handle_exception
455. self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in dispatch
492. response = handler(request, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/generics.py" in post
192. return self.create(request, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/mixins.py" in create
21. self.perform_create(serializer)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/mixins.py" in perform_create
26. serializer.save()
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in save
216. '`create()` did not return an object instance.'
Exception Type: AssertionError at /dqf_api/ReceiptLog/
Exception Value: `create()` did not return an object instance.
models.py
class TestCaseCommandRun(models.Model):
# fields ..Doesn't have id field as the database doesn't have it
class Meta:
managed = False
db_table = 'test_case_command_run'
unique_together = (('team_name', 'suite_name', 'suite_run_id', 'case_name', 'command_name'),)
class TestCaseCommandRunResults(models.Model):
# fields ..Doesn't have id field as the database doesn't have it
class Meta:
managed = False
db_table = 'test_case_command_run_results'
unique_together = (('suite_run_id', 'command_run_id', 'rule_name', 'result_id'),)
views.py
class TestCaseCommandRunViewSet(viewsets.ModelViewSet):
queryset = models.TestCaseCommandRunViewSet.objects.values(team_name','suite_name','suite_run_id', 'case_name','command_name','command_run_id','run_start','run_end','result','run_status')
serializer_class = serializers.TestCaseCommandRunViewSet
class TestCaseCommandRunResultsViewSet(viewsets.ModelViewSet):
queryset = models.TestCaseCommandRunResultsViewSet.objects.values('suite_run_id','command_run_id','rule_name', 'result_id',
'result','expected_values','actual_values','report_values','extended_values')
serializer_class = serializers.TestCaseCommandRunResultsViewSet
class ReceiptLogViewSet(CreateAPIView):
serializer_class = serializers.ReceiptLogSerializer.ReceiptLogSerializerClass
serializers.py
class TestCaseCommandRunResultsViewSet(serializers.ModelSerializer):
class Meta:
model = models.TestCaseCommandRunResultsViewSet
fields = ['suite_run_id','command_run_id','rule_name', 'result_id','result','expected_values','actual_values','report_values','extended_values']
class TestCaseCommandRunSerializer(serializers.ModelSerializer):
class Meta:
model = models.TestCaseCommandRunSerializer
fields = [team_name','suite_name','suite_run_id', 'case_name','command_name','command_run_id','run_start','run_end','result','run_status']
class ReceiptLogSerializerClass(serializers.Serializer):
team_name = serializers.CharField(max_length=30)
suite_name = serializers.CharField(max_length=100)
suite_run_id = serializers.CharField(max_length=50,required=False, allow_blank=True, default=datetime.now().strftime('%Y%m%d%H%M%S'))
case_name = serializers.CharField(max_length=50)
command_name = serializers.CharField(max_length=50)
command_run_id = serializers.CharField(max_length=50,required=False, allow_blank=True, default='Not Applicable')
run_start = serializers.DateTimeField(default=datetime.now, required=False)
run_end = serializers.DateTimeField(default=datetime.now, required=False)
result = serializers.CharField(max_length=10, default='Not Applicable')
run_status = serializers.CharField(max_length=10)
rule_name = serializers.CharField( max_length=50, required=False, allow_blank=True, default='Not Applicable')
expected_values = serializers.CharField(max_length=200, allow_blank=True)
actual_values = serializers.CharField(max_length=200, allow_blank=True)
report_values = serializers.CharField(max_length=200, allow_blank=True)
extended_values = serializers.CharField(max_length=200, allow_blank=True)
def create(self, validated_data):
# command_run_data_list = []
command_run_results_data_list = []
raw_data_list = []
many = isinstance(validated_data, list)
if many:
raw_data_list = validated_data
else:
raw_data_list.append(validated_data)
result_id = 1
for data_row in raw_data_list:
new_command_run_entry = {
'team_name': data_row.get('team_name'),
'suite_name': data_row.get('suite_name'),
'suite_run_id': data_row.get('suite_run_id'),
'case_name': data_row.get('case_name'),
'command_name': data_row.get('command_name'),
'command_run_id': data_row.get('command_run_id'),
'run_start': data_row.get('run_start'),
'run_end': data_row.get('run_end'),
'result': data_row.get('result'),
'run_status': data_row.get('run_status')
}
command_run_data_list.append(new_command_run_entry)
new_command_run_result_entry = {
'suite_run_id': data_row.get('suite_run_id'),
'command_run_id': data_row.get('command_run_id'),
'rule_name': data_row.get('rule_name'),
'result_id': result_id,
'result': data_row.get('result'), # PASS or FAIL
'expected_values': data_row.get('expected_values'),
'actual_values': data_row.get('actual_values'),
'report_values': data_row.get('report_values'),
'extended_values': data_row.get('extended_values'),
}
command_run_results_data_list.append(new_command_run_result_entry)
result_id += 1
for item in command_run_results_data_list:
response_run_results = models.TestCaseCommandRunResults.objects.create(**item)
for item in command_run_data_list:
response_run = models.TestCaseCommandRun.objects.create(**item)
urls.py
router = routers.DefaultRouter()
router.register(r'test_case_command_runs', views.TestCaseCommandRunViewSet)
router.register(r'test_case_command_run_results', views.TestCaseCommandRunResultsViewSet)
urlpatterns = [
url(r'^buildInfo', views.build_info),
url(r'^isActive', views.is_active),
url(r'^dqf_api/', include(router.urls)),
url(r'^dqf_api/ReceiptLog/', views.ReceiptLogView.ReceiptLogViewSet.as_view(), name='ReceiptLog')]
非常感谢您的帮助。我是Django和DRF的新手
答案 0 :(得分:1)
您的序列化程序的create
方法必须返回其表示的对象的实例。另外,您不应该在序列化程序内部进行迭代来创建实例,而应该在视图上完成:您要遍历数据,每次迭代都调用序列化程序。
答案 1 :(得分:1)
更新了serializers.py文件,使其包含以下代码
class ReceiptLogSerializerClass(serializers.Serializer):
#Fields
def create(self, validated_data):
raw_data_list = []
many = isinstance(validated_data, list)
if many:
raw_data_list = validated_data
else:
raw_data_list.append(validated_data)
result_id = 1
for data_row in raw_data_list:
new_command_run_entry = {
'team_name': data_row.get('team_name'),
'suite_name': data_row.get('suite_name'),
'suite_run_id': data_row.get('suite_run_id'),
'case_name': data_row.get('case_name'),
'command_name': data_row.get('command_name'),
'command_run_id': data_row.get('command_run_id'),
'run_start': data_row.get('run_start'),
'run_end': data_row.get('run_end'),
'result': data_row.get('result'),
'run_status': data_row.get('run_status')
}
response = TestCaseCommandRunSerializer.create(TestCaseCommandRunSerializer(),validated_data= new_command_run_entry)
new_command_run_result_entry = {
'suite_run_id': data_row.get('suite_run_id'),
'command_run_id': data_row.get('command_run_id'),
'rule_name': data_row.get('rule_name'),
'result_id': result_id,
'result': data_row.get('result'), # PASS or FAIL
'expected_values': data_row.get('expected_values'),
'actual_values': data_row.get('actual_values'),
'report_values': data_row.get('report_values'),
'extended_values': data_row.get('extended_values'),
}
response = TestCaseCommandRunResultsSerializer.create(TestCaseCommandRunResultsSerializer(),validated_data= new_command_run_result_entry)
logger.info(" new_command_run_result_entry response %s" % response)
result_id += 1
return validated_data
我没有正确反序列化数据,因此遇到了多个问题。 返回validated_data 解决了所有错误,现在我可以通过单个API将数据发布到多个模型中。
要在单个API调用中发布多个有效负载,请在ReceiptLogViewSet中的行下方添加
def get_serializer(self, *args, **kwargs):
if "data" in kwargs:
data = kwargs["data"]
if isinstance(data, list):
kwargs["many"] = True
return super(ReceiptLogViewSet, self).get_serializer(*args, **kwargs)
参考:Django rest framework cannot deal with multple objects in model viewset
答案 2 :(得分:0)
序列化器ReceiptLogSerializerClass必须是 ModelSerializer ,而不是序列化器