【问题标题】:Django - sending JSON arrary on POST requestDjango - 在 POST 请求上发送 JSON 数组
【发布时间】:2018-06-06 05:55:31
【问题描述】:

我正在根据数据库中可用的记录数创建一个动态表单。 输入字段在渲染期间动态设置。一旦设置了值,我希望将它们批量插入到数据库中。 (我使用modelSerializer类进行序列化)

例如

<form id="issue_form">
<input name="issue" value="random"/>
<input name="issue" value="sensor"/>
<input name="issue" value="human"/>
<input name="issue" value="pc"/>
</form>

<script>
$(docment).on('submit','#issue_form',function(event){
     event.preventDefault();
var data = $(this).serializeArray();

$.ajax({"url":"api/data",data :data }).done(function(res){
   console.log(data)
})
})

型号:

class ParetoAnalysis(models.Model):
    shift                   = models.ForeignKey(Shift, on_delete=models.CASCADE)
    line                    = models.ForeignKey(Line, on_delete=models.CASCADE)
    start_time              = models.DateTimeField(default=datetime.now)
    end_time                = models.DateTimeField(default=datetime.now)
    end_point               = models.ForeignKey(EndPoint, on_delete=models.CASCADE)
    issue                   = models.ForeignKey(DownTimeIssue, on_delete=models.CASCADE)
    custom_comments         = models.CharField(max_length=1000,blank=True)
    created_by              = models.ForeignKey(User, on_delete=models.CASCADE,null=True)
    created_date            = models.DateTimeField(default=datetime.now,blank=False)

序列化器:

class ParetoAnalysisSerializer(serializers.ModelSerializer):
    duration = serializers.SerializerMethodField()        #duration in seconds

    issue = serializers.PrimaryKeyRelatedField(
    read_only=False, queryset=DownTimeIssue.objects.all()) 

    line = serializers.PrimaryKeyRelatedField(
    read_only=False, queryset=Line.objects.all())

    shift = serializers.PrimaryKeyRelatedField(
    read_only=False, queryset=Shift.objects.all())

    end_point = serializers.PrimaryKeyRelatedField(
    read_only=False, queryset=EndPoint.objects.all())

    #created_by_id = 1 #serializers.SerializerMethodField('_user')
    created_by_id = serializers.SerializerMethodField()


    def get_created_by_id(self,pareto):
        return 1

    def get_duration(self, pareto):
        return  (pareto.end_time-pareto.start_time).seconds

    class Meta:
        model = ParetoAnalysis
        fields = ('custom_comments', 'end_point', 'issue','line','shift', 'created_by_id', 'created_date', 'end_time', 'start_time','duration')

查看

class ParetoAnalysisViewSet(viewsets.ModelViewSet):
    queryset = ParetoAnalysis.objects.all()
    serializer_class = ParetoAnalysisSerializer

    def create(self, request):
        serializer = self.get_serializer(data=request.data, many=True)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

我想实现在模型的发布请求上存储批量 JSON 值。

例如

json = [{"name":"random"},{"name":"sensor"},{"name":"human"},{"name":"pc"}]

默认 API 表单提交时的错误日志

    return  (pareto.end_time-pareto.start_time).seconds
    AttributeError: 'collections.OrderedDict' object has no attribute 'end_time'

发送批量 json 时的错误日志

Traceback (most recent call last):
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\exception.py", line 35, in inner
    response = get_response(request)
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 158, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 156, in _get_response
    response = response.render()
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\template\response.py", line 106, in render
    self.content = self.rendered_content
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\rest_framework\response.py", line 72, in rendered_content
    ret = renderer.render(self.data, accepted_media_type, context)
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\rest_framework\renderers.py", line 718, in render
    context = self.get_context(data, accepted_media_type, renderer_context)
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\rest_framework\renderers.py", line 691, in get_context
    'post_form': self.get_rendered_html_form(data, view, 'POST', request),
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\rest_framework\renderers.py", line 496, in get_rendered_html_form
    return self.render_form_for_serializer(existing_serializer)
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\rest_framework\renderers.py", line 522, in render_form_for_serializer
    serializer.data,
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\rest_framework\serializers.py", line 742, in data
    ret = super(ListSerializer, self).data
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\rest_framework\serializers.py", line 266, in data
    self._data = self.get_initial()
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\rest_framework\serializers.py", line 577, in get_initial
    return self.to_representation(self.initial_data)
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\rest_framework\serializers.py", line 660, in to_representation
    self.child.to_representation(item) for item in iterable
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\rest_framework\serializers.py", line 660, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "E:\Personal\GM\Godrej\Mirror Code v1\report\serializers.py", line 82, in to_representation
    data =  super(ParetoAnalysisSerializer, self).to_representation(instance)
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\rest_framework\serializers.py", line 504, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "C:\Users\5450\AppData\Local\Programs\Python\Python36-32\lib\site-packages\rest_framework\relations.py", line 257, in to_representation
    return value.pk
AttributeError: 'int' object has no attribute 'pk'

【问题讨论】:

    标签: python django django-models django-rest-framework


    【解决方案1】:

    您需要为此内部视图集 create() 方法使用序列化程序的 many=True 参数:

    from rest_framework import status
    from rest_framework.response import Response
    
    class IssueViewSet(viewsets.ModelViewSet):
        queryset = Issue.objects.all()
        serializer_class = IssueSerializer
    
        def create(self, request):
            if not isinstance(request.data, dict):
                serializer = self.get_serializer(data=request.data, many=True)
            else:
                serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
    

    【讨论】:

    • 在这种情况下我应该使用 ListSerializer 而不是 ModelSerializer 吗?
    • @Shahabaz 不,Django 会自动选择正确的实例。
    • 好的。以这种方式更新代码时出现了一些错误。你能帮我看看错误日志吗?
    • @Shahabaz 您是否在序列化程序的元数据中引用了问题字段:fields = ('id', 'issue')?在你的问题中它没有被引用。
    • 我不好,它已经有引号了。仅供参考,现有的 API 工作得很好,我想要这个批量插入。 (已更新问题)
    猜你喜欢
    • 2017-09-18
    • 2016-09-29
    • 2014-10-07
    • 2013-08-22
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多