Ax ios POST отправляет данные Nonetype в Django Rest Framework - PullRequest
0 голосов
/ 03 августа 2020

Мне трудно понять, как отправить данные формы через ax ios на мой Django бэкэнд, используя DRF. Формы Classi c Django работают правильно.

Всякий раз, когда я пытаюсь опубликовать его с помощью модальной формы React, я получаю новый ввод в моей базе данных, который полностью состоит из None (нули, я думаю? ). Сериализатор, похоже, не прерывает его, и я получаю статус HTTP 201. Я понятия не имею, где искать причину этой проблемы, думаю, я перепробовал почти все.

Я отправлю свой код, чтобы более опытный наблюдатель мог уловить root этой ошибки.

components.js / lookup. js

import axios from "axios";

const csrftoken = getCookie("csrftoken");

const api = axios.create({
  baseURL: `http://localhost:8000`,
  headers: {
    "X-CSRFToken": csrftoken,
  },
});

function getCookie(name) {
  // gets csrf cookie
  var cookieValue = null;
  if (document.cookie && document.cookie !== "") {
    var cookies = document.cookie.split(";");
    for (var i = 0; i < cookies.length; i++) {
      var cookie = cookies[i].trim();
      // Does this cookie string begin with the name we want?
      if (cookie.substring(0, name.length + 1) === name + "=") {
        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
        break;
      }
    }
  }
  return cookieValue;
}

export async function apiLookup(method, endpoint, callback, data) {
  try {
    if (method === "GET") {
      api.get(`${endpoint}`).then((response) => {
        callback(response.data, response.status);
      });
    } else if (method === "POST") {
      axios(
        {
          method: "post",
          url: `http://localhost:8000${endpoint}`,
          data: data,
        },
        {
          headers: {
            "Content-Type": "multipart/form-data",
          },
        }
      );
    }
  } catch (error) {
    console.log(error);
  }
}

сотрудник / поиск. js

import { apiLookup } from "../lookup";

export async function apiCreateEmployee(callback, data) {
  let endpoint = "/api/employee/create-employee";
  console.log(data);
  apiLookup("POST", endpoint, callback, data);
}

addform. js

import React, { createRef } from "react";
import { apiCreateEmployee } from "./lookup";

export function EmployeeCreate(props) {
  const firstNameRef = createRef();
  const lastNameRef = createRef();
  const departmentRef = createRef();
  const positionRef = createRef();
  const salaryRef = createRef();
  const contactNumberRef = createRef();
  const imageRef = createRef();

  const { didAddEmployee } = props;
  const handleBackendUpdate = (response, status) => {
    if (status === 201) {
      didAddEmployee(response);
    } else {
      console.log(response);
      alert("An error occured, please try again");
    }
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    const newEmployee = {
      first_name: firstNameRef.current.value,
      last_name: lastNameRef.current.value,
      department: departmentRef.current.value,
      position: positionRef.current.value,
      salary: salaryRef.current.value,
      contact_number: contactNumberRef.current.value,
      image: imageRef.current.files[0],
    };
    apiCreateEmployee(handleBackendUpdate, newEmployee);
  };

  const fieldClass = "form-control w-75 p-2 my-2 mx-auto";

  return (
    <div className={props.className}>
      <form
        className="w-100 d-flex justify-content-center flex-column align-content-around mx-auto"
        onSubmit={handleSubmit}
      >
        <textarea
          ref={firstNameRef}
          required={true}
          className={fieldClass}
          name="first_name"
          placeholder="First name"
        ></textarea>
        <textarea
          ref={lastNameRef}
          required={true}
          className={fieldClass}
          name="last_name"
          placeholder="Last name"
        ></textarea>
        <textarea
          ref={departmentRef}
          required={true}
          className={fieldClass}
          name="department"
          placeholder="Department"
        ></textarea>
        <textarea
          ref={positionRef}
          required={true}
          className={fieldClass}
          name="position"
          placeholder="Position"
        ></textarea>
        <textarea
          ref={salaryRef}
          required={true}
          className={fieldClass}
          name="salary"
          placeholder="Salary"
        ></textarea>
        <textarea
          ref={contactNumberRef}
          required={true}
          className={fieldClass}
          name="contact_number"
          placeholder="Contact number"
        ></textarea>
        <input
          type="file"
          ref={imageRef}
          required={false}
          className={fieldClass}
          placeholder="Photo"
        ></input>

        <button type="submit" className="btn btn-primary my-3 w-50 mx-auto">
          Add new employee
        </button>
      </form>
    </div>
  );
}

employee / serializers.py

from rest_framework import serializers
from .models import Employee


class EmployeeSerializer(serializers.ModelSerializer):
    first_name = serializers.SerializerMethodField(read_only=True)
    last_name = serializers.SerializerMethodField(read_only=True)
    department = serializers.SerializerMethodField(read_only=True)
    position = serializers.SerializerMethodField(read_only=True)
    salary = serializers.CharField(read_only=True)
    contact_number = serializers.CharField(read_only=True)
    image = serializers.ImageField(allow_empty_file=True, required=False)

    class Meta:
        model = Employee
        fields = ['first_name', 'last_name', 'department',
                  'position', 'salary', 'contact_number', 'image']

    def get_first_name(self, obj):
        return obj.first_name

    def get_last_name(self, obj):
        return obj.last_name

    def get_department(self, obj):
        return obj.department

    def get_position(self, obj):
        return obj.position

    def get_salary(self, obj):
        return obj.salary

    def get_contact_number(self, obj):
        return obj.contact_number

    def get_image(self, obj):
        print(obj.image)
        return obj.image


class EmployeeCreateSerializer(serializers.ModelSerializer):
    first_name = serializers.SerializerMethodField(read_only=True)
    last_name = serializers.SerializerMethodField(read_only=True)
    department = serializers.SerializerMethodField(read_only=True)
    position = serializers.SerializerMethodField(read_only=True)
    salary = serializers.CharField(read_only=True)
    contact_number = serializers.CharField(read_only=True)
    image = serializers.ImageField(allow_empty_file=True, required=False)

    class Meta:
        model = Employee
        fields = ['first_name', 'last_name', 'department',
                  'position', 'salary', 'contact_number', 'image']

    def validate_salary(self, value):
        if not value:
            return 0
        try:
            return int(value)
        except ValueError:
            raise serializers.ValidationError('You must supply an integer')

    def validate_contact_number(self, value):
        if not value:
            return 0
        try:
            return int(value)
        except ValueError:
            raise serializers.ValidationError('You must supply an integer')

    def validate_content(self, value):
        if len(value) > settings.MAX_TEXT_LENGTH:
            raise serializers.ValidationError(
                'Maximum text length exceeded.')
        return value

    def get_first_name(self, obj):
        return obj.first_name

    def get_last_name(self, obj):
        return obj.last_name

    def get_department(self, obj):
        return obj.department

    def get_position(self, obj):
        return obj.position

    def get_salary(self, obj):
        return obj.salary

    def get_contact_number(self, obj):
        return obj.contact_number

    def get_image(self, obj):
        print(obj.image)
        return obj.image

employee / models.py

from django.db import models


class EmployeeManager(models.Manager):
    def get_queryset(self):
        return EmployeeQuerySet(self.model, using=self._db)

    def search(self, query=None):
        return self.get_queryset().search(query=query)


class EmployeeQuerySet(models.QuerySet):
    def search(self, query=None):
        qs = self
        if query is not None:
            or_lookup = (Q(first_name__icontains=query) | Q(
                last_name__icontains=query))
            qs = qs.filter(or_lookup).distinct()
        return qs


class Employee(models.Model):
    first_name = models.CharField(blank=False, null=True, max_length=30)
    last_name = models.CharField(blank=False, null=True, max_length=30)
    department = models.CharField(blank=False, null=True, max_length=50)
    position = models.CharField(blank=False, null=True, max_length=30)
    salary = models.CharField(blank=False, max_length=10)
    contact_number = models.CharField(blank=False, max_length=10)
    image = models.ImageField(
        default='profile_pic.jpg', upload_to='employee_photos')

    def __str__(self):
        return f'{self.first_name} {self.last_name}'

    objects = EmployeeManager()

Я с удовольствием опубликую что-нибудь еще, но я думаю, что проблема может быть где-то в этих файлах .

Заранее большое спасибо за любой вклад в решение.

Ура

1 Ответ

1 голос
/ 03 августа 2020

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

class EmployeeSerializer(serializers.ModelSerializer):  
    class Meta:
        model = Employee
        fields = ['first_name', 'last_name', 'department',
                  'position', 'salary', 'contact_number', 'image']

Проверьте свое представление, если у вас есть составной синтаксический анализатор.

проверьте документы для дальнейшего information

попробуйте зарегистрировать ваш request.data, чтобы проверить, какие данные действительно опубликованы на ax ios.

...