drf-仅将序列化器用于post()方法

时间:2019-03-16 23:43:34

标签: django django-rest-framework serializer

我正在使用Django Rest Framework。我定义了一个序列化器-没有模型的ReceiptLog,当对收据日志发出post()请求时,应该在TestCaseCommandRun和TestCaseCommandRunResults中创建条目。收据日志在数据库中不存在,我只是将其用作端点来接受组合的有效负载并在基础表中创建条目。我不希望对ReceiptLog序列化程序执行get()请求。

下面是代码段。

问题:

  1. 如何确保只有post()工作并且get()返回异常
  2. 使用串行器是最好的方法吗?还是应该使用视图集?
  3. 我有一个可浏览的API,其中列出了urls.py中的所有api。因此,当我单击收据日志api时,它不应显示任何数据,因为不允许使用get()。我该如何确保?

models.py

class TestCaseCommandRun(models.Model):
   # fields
   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
    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(viewsets.ViewSet):
    serializer_class = serializers.ReceiptLog

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 ReceiptLogSerializer(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()
    run_end = serializers.DateTimeField()
    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)
    actual_values = serializers.CharField(max_length=200)
    report_values = serializers.CharField(max_length=200)
    extended_values = serializers.CharField(max_length=200)

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

    CommandRunResultSerializer = \
        TestCaseCommandRunResultsSerializer(
            data=command_run_results_data_list,
            many=isinstance(command_run_results_data_list, list))
    CommandRunResultSerializer.is_valid(raise_exception=True)
    self.perform_create(CommandRunResultSerializer)

    CommandRunSerializer = \
        TestCaseCommandRunSerializer(
            data=command_run_data_list,
            many=isinstance(command_run_data_list, list))
    CommandRunSerializer.is_valid(raise_exception=True)
    self.perform_create(CommandRunSerializer)

urls.py

router = routers.DefaultRouter()

router.register(r'test_case_command_runs', views.TestCaseCommandRunViewSet)
router.register(r'test_case_command_run_results', views.TestCaseCommandRunResultsViewSet)
router.register(r'receipt_log', views.ReceiptLogViewSet, base_name='ReceiptLog')

urlpatterns = [
    url(r'^buildInfo', views.build_info),
    url(r'^isActive', views.is_active),
    url(r'^dqf_api/', include(router.urls)),
]

我们非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

DRF中的视图非常模块化,您可以选择仅使用所需的HTTP方法。对于您而言,最好的选择是使用CreateAPIView

from rest_framework.generics import CreateAPIView


class ReceiptLogView(CreateAPIView):
    serializer_class = serializers.ReceiptLog

这还将确保使用GET或其他方法时,即使在可浏览的API中,也将返回不允许的405方法

我真的不理解您的第二个问题,因为视图(和视图集)和序列化器具有不同的用途,并且不易混淆。

我也建议您改善命名。序列化程序名称应以Serializer结尾,以免将它们与模型混淆。

答案 1 :(得分:0)

我更新了urls.py以包含以下行

url(r'^dqf_api/ReceiptLog/', views.ReceiptLogView.ReceiptLogViewSet.as_view(), name='ReceiptLog')