【问题标题】:what enctype do I choose to keep option value as an object and keep the support type app/json?我选择什么 enctype 将选项值保留为对象并保留支持类型 app/json?
【发布时间】:2019-06-12 05:53:14
【问题描述】:

我正在尝试将选项的值作为 POST 表单中的对象发送,因此我使用 enctype='text/plain' 来获取对象而不是字符串。同时支持的媒体类型为'application/json'

这里是模板:

    <form class="" action="/api/meal_planner/" method="post" enctype='text/plain'>
{% csrf_token %}

<h3> Starters </h3>

{% for food in foods %}
  {% if food.type == 'starter' %}
    <div id="f{{ forloop.counter }}">
      <h3> {{ food.display_name }} </h3>
      <div class="details">
        <ul>
          <li>calories: {{food.cal}}</li>
          <li>carbs: {{food.carbs}}</li>
          <li>carbs: {{food.carbs}}</li>
          <li>fibers: {{food.fibers}}</li>
          <li>proteins: {{food.proteins}}</li>
          <li>lipids: {{food.lipids}}</li>
        </ul>
      </div>
      <div class="image">
        <img src="{{food.imgUrl}}">
      </div>
    </div>
  {% endif %}
{% endfor %}

<div class="select">
  <select name='starter'>
    {% for food in foods %}
      {% if food.type == 'starter' %}
    <option value='{"display_name":"{{food.display_name}}","cal":{{food.cal}}}'>{{ food.display_name }} </option>
    {% endif %}
  {% endfor %}
  </select>
</div>

你看到的选项是:

<option value='{"display_name":"{{food.display_name}}","cal":{{food.cal}}}'>{{ food.display_name }} </option>

所以我可以拥有这样的身体: Body of POST

这是 Django API:

@api_view(["POST"])
def FoodResponse(foodData):
    try:
        #defining variables
        calMoy=500
        percentage=0.1
        calSum=0
        donnee = json.loads(json.dumps(foodData.data))
        print (donnee)
        calSum= calSum + donnee["starter"]["cal"]+ donnee["dish"]["cal"]+ donnee["desert"]["cal"]
        if ( (calSum < calMoy*(1-percentage)) or (calSum > calMoy*(1+percentage)) ):
            return JsonResponse({
            "status": "KO",
            "food": donnee
            })
        else:
            return JsonResponse({
            "status": "OK",
            "food": donnee
            })
    except ValueError as e:
        return Response(e.args[0],status.HTTP_400_BAD_REQUEST)

这是错误:

Error unsupported media type

【问题讨论】:

    标签: html django django-rest-framework django-templates


    【解决方案1】:

    Django Rest Framework 默认允许application/jsonapplication/x-www-form-urlencoded 的请求,除非您编写自己的text/plain 解析器(有一个example in the docs),否则text/plain 请求将被拒绝。

    但是,我建议您不要尝试这样做。 与其尝试使用纯文本编码将 JSON 作为表单中每个选择选项的值发送,不如这样做更明智使用每个Food对象的主键,然后使用主键在视图中查找Food对象。查找后,您可以检索卡路里和任何其他数据。

    因此,在表单中,删除 enctype="text/plain" 并修改构建下拉菜单的方式以使用 Food 主键:

    <select name='starter'>
        {% for food in foods %}
            {% if food.type == 'starter' %}
                <option value="{{ food.pk }}">{{ food.display_name }} </option>
            {% endif %}
        {% endfor %}
    </select>
    

    对菜肴和甜点的其他下拉菜单执行相同操作。

    然后将视图修改为如下所示:

    @api_view(["POST"])
    def FoodResponse(request):
        try:
            #defining variables
            calMoy=500
            percentage=0.1
            calSum=0
    
            # Lookup the food objects up using the primary key
            starter = Food.objects.get(pk=request.POST['starter'])
            dish = Food.objects.get(pk=request.POST['dish'])
            desert = Food.objects.get(pk=request.POST['desert'])
    
            # Retrieve the calories and calculate the total
            calSum= calSum + starter.cal+ dish.cal + desert.cal
    
            ...
    

    【讨论】:

    • 感谢您的回复,但这里的问题是我正在处理一个没有主键的食物数据库,即使按名称也无法区分食物对象。所以我必须将所需的数据作为 JSON 发送。顺便说一句,我找到了一个解决方案,但它有点“不专业”,我希望让它变得更好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 2016-08-16
    • 1970-01-01
    • 2011-09-26
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    相关资源
    最近更新 更多