Какой энтип я выберу, чтобы сохранить значение параметра как объект и сохранить тип поддержки app / json? - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь отправить значение параметра в виде объекта в форме 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>

Так что я могу получить тело вот так: Кузов ПОСТ

А это 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)

А это ошибка:

Ошибка неподдерживаемого типа носителя

1 Ответ

0 голосов
/ 18 января 2019

Django Rest Framework разрешает запросы по умолчанию application/json или application/x-www-form-urlencoded, и если вы не напишите свой собственный анализатор text/plain (в документах есть пример ), запрос 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

        ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...