Axios 到 django-backend post 图像失败
Axios to django-backend post image fail
我正在使用 React 前端通过 axios 与 Django 后端进行通信。出于某种原因,我无法 post 形成包含图像的表格。我通过 Postman 测试了我的 django 后端,它运行良好。
后端在终端显示code 200为成功但未保存数据,前端未通过错误
如果我排除了图像,表单可以 post 成功。请检查下面我的代码;
form.js 文件
import React, { useState } from 'react';
import { Helmet } from 'react-helmet';
import axios from 'axios';
import { connect } from 'react-redux';
import { setAlert } from '../actions/alert';
import './ApplicationForm.css';
import { useNavigate } from 'react-router-dom';
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { IconButton } from '@mui/material';
function ApplicationForm({ setAlert }) {
const [show, setShow] = useState (false);
const navigate=useNavigate();
const [formData, setFormData] = useState({
pasport_number: '', first_name: '', last_name: '', passport_photo: ''
});
const { pasport_number, first_name, last_name, passport_photo } = formData;
const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value });
console.log (formData)
const onSubmit = e => {
e.preventDefault();
const config = {
headers: {
'Content-Type': 'application/json'
}
};
axios.post(`${process.env.REACT_APP_API_URL}/api/application-form/`, { pasport_number, first_name, last_name, passport_photo }, config)
.then(_res => {
navigate('/');
setAlert('Application Submitted Successfully', 'success');
})
.catch(_err => {
setAlert('Error with Sending Application', 'error');
})
};
return (
<div className='applicationForm'>
<div className='wrapper'>
<Helmet>
<title>Prosperity - Visa Application Form</title>
<meta
name='description'
content='Filling Application Form '
/>
</Helmet>
<div className='applicationForm__wrapper'>
<h1 className='applicationForm__title'>Application Form</h1>
<hr className='appform__hr'/>
<form className='applicationForm__form' onSubmit={e => onSubmit(e)}>
<div className='form__wrap'>
<hr className='appform__hr'/>
<p className='passport__section__title'>Enter or Import Passport Details</p>
<div className='input_grp'>
<div className='input_wrap input_wrap__bt'>
<p className='expand__p'>Enter Passport details</p>
<IconButton onClick={()=> setShow(true)}>
<ExpandMoreIcon className='Expand__bt'/>
</IconButton>
<IconButton onClick={()=> setShow(false)}>
<ExpandLessIcon className='Expand__less__bt'/>
</IconButton>
</div>
<div className='input_wrap input_wrap__bt import__passport'>
<label className='applicationForm__form__label' htmlFor='passport_photo'>Import Passport Image</label>
<input
className='input__for__two import__passport'
name='passport_photo'
type='file'
accept='image/*,.pdf'
placeholder='Import Passport'
onChange={e => onChange(e)}
value={passport_photo}
required
/>
</div>
</div>
{ show?
<>
<div className='input_grp'>
<div className='input_wrap'>
<label className='applicationForm__form__label appForm__subject' htmlFor='first_name'>First Name</label>
<input
className='applicationForm__form__input input__for__two'
name='first_name'
type='text'
placeholder='First Name *'
onChange={e => onChange(e)}
value={first_name}
required
/>
</div>
<div className='input_wrap'>
<label className='applicationForm__form__label' htmlFor='last_name'>Last Name</label>
<input
className='applicationForm__form__input input__for__two'
name='last_name'
type='text'
placeholder='Last Name *'
onChange={e => onChange(e)}
value={last_name}
required
/>
</div>
</div>
<div className='input_grp'>
<div className='form__wrap'>
<label className='applicationForm__form__label' htmlFor='pasport_number'>Passport Number</label>
<input
className='applicationForm__form__input input__for__two'
name='pasport_number'
type='text'
placeholder='Passport Number'
onChange={e => onChange(e)}
value={pasport_number}
required
/>
</div>
</div>
</>
:null
}
<hr className='appform__hr'/>
<button className='contact__form__button' htmltype='submit'>Send</button>
</div>
</form>
</div>
</div>
</div>
)
}
export default connect(null, { setAlert })(ApplicationForm);
console.log(表格数据);
{pasport_number: 'test3', first_name: 'test1', last_name: 'test2', passport_photo: 'C:\fakepath\signature.jpg'}
first_name: "test1"
last_name: "test2"
pasport_number: "test3"
passport_photo: "C:\fakepath\signature.jpg"
[[Prototype]]: Object
更新的形式包括 react-file-base64 ;
import React, { useState } from 'react';
import { Helmet } from 'react-helmet';
import axios from 'axios';
import { connect } from 'react-redux';
import { setAlert } from '../actions/alert';
import './ApplicationForm.css';
import { useNavigate } from 'react-router-dom';
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { IconButton } from '@mui/material';
import FileBase from "react-file-base64";
function ApplicationForm({ setAlert }) {
const [show, setShow] = useState (false);
const navigate=useNavigate();
const [formData, setFormData] = useState({
pasport_number: '', passport_photo: ''
});
const { pasport_number, passport_photo } = formData;
const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value });
console.log (formData);
const onSubmit = e => {
e.preventDefault();
const config = {
headers: {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json'
}
};
axios.post(`${process.env.REACT_APP_API_URL}/api/application-form/`, { pasport_number, passport_photo }, config)
.then(_res => {
setAlert('Application Submitted Successfully', 'success');
})
.catch(_err => {
setAlert('Error with Sending Application', 'error');
})
};
return (
<div className='applicationForm'>
<div className='wrapper'>
<Helmet>
<title>Prosperity - Visa Application Form</title>
<meta
name='description'
content='Filling Application Form '
/>
</Helmet>
<div className='applicationForm__wrapper'>
<h1 className='applicationForm__title'>Application Form</h1>
<hr className='appform__hr'/>
<form className='applicationForm__form' onSubmit={e => onSubmit(e)} enctype="multipart/form-data">
<div className='form__wrap'>
<hr className='appform__hr'/>
<p className='passport__section__title'>Enter or Import Passport Details</p>
<div className='input_grp'>
<div className='input_wrap input_wrap__bt'>
<p className='expand__p'>Enter Passport details</p>
<IconButton onClick={()=> setShow(true)}>
<ExpandMoreIcon className='Expand__bt'/>
</IconButton>
<IconButton onClick={()=> setShow(false)}>
<ExpandLessIcon className='Expand__less__bt'/>
</IconButton>
</div>
<FileBase
type="file"
multiple={false}
onDone={({ base64 }) =>
setFormData({ ...formData, passport_photo: base64 })}
/>
</div>
{ show?
<>
<div className='input_grp'>
<div className='form__wrap'>
<label className='applicationForm__form__label' htmlFor='pasport_number'>Passport Number</label>
<input
className='applicationForm__form__input input__for__two'
name='pasport_number'
type='text'
placeholder='Passport Number'
onChange={e => onChange(e)}
value={pasport_number}
required
/>
</div>
</div>
</>
:null
}
<hr className='appform__hr'/>
<button className='contact__form__button' htmltype='submit'>Send</button>
</div>
</form>
</div>
</div>
</div>
)
}
export default connect(null, { setAlert })(ApplicationForm);
已更新 console.log ;
{pasport_number: 'TEST99', passport_photo: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB4sA…LzzTqZ8wa/uf//J//+/8PoXjMydjnS20AAAAASUVORK5CYII='}
pasport_number: "TEST99"
passport_photo: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB4s
[[Prototype]]: Object
django settings.py ;
from datetime import timedelta
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = 'xxx'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'accounts.apps.AccountsConfig',
'application_form.apps.ApplicationFormConfig',
'social.apps.SocialConfig',
'contacts.apps.ContactsConfig',
'rest_framework',
'djoser',
'corsheaders',
'rest_framework_simplejwt.token_blacklist'
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'pros.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'build')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'prosperity.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'prosdb',
'USER': 'postgres',
'PASSWORD': 'xxxxx',
'HOST': 'localhost'
}
}
# email addition
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.xxxx.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'xxx@xxx.xx'
EMAIL_HOST_PASSWORD = 'xxxxx'
EMAIL_USE_TLS = True
MAIL_FROM_ADDRESS='xxxxxx'
# Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/
LANGUAGE_CODE = 'en-GB'
TIME_ZONE = 'CET'
DATE_INPUT_FORMATS = [
'%d-%m-%Y', '%Y-%m-%d',
'%m/%d/%Y', '%m/%d/%y',
'%b %d %Y', '%b %d, %Y',
'%d %b %Y', '%d %b, %Y',
'%B %d %Y', '%B %d, %Y',
'%d %B %Y', '%d %B, %Y',
]
USE_I18N = True
USE_TZ = True
DATA_UPLOAD_MAX_NUMBER_FIELDS = None
STATIC_URL = 'static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'build/static')
]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated'
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.MultiPartParser'
],
}
CORS_ORIGIN_ALLOW_ALL = True
FILE_UPLOAD_PERMISSIONS=0o640
# Token settings
SIMPLE_JWT = {
'AUTH_HEADER_TYPES': ('JWT',),
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'AUTH_TOKEN_CLASSES': (
'rest_framework_simplejwt.tokens.AccessToken',
)
}
DJOSER = {
'LOGIN_FIELD':'email',
'USER_CREATE_PASSWORD_RETYPE': True,
'USERNAME_CHANGED_EMAIL_CONFIRMATION': True,
'PASSWORD_CHANGED_EMAIL_CONFIRMATION': True,
'SEND_CONFIRMATION_EMAIL': True,
'SET_USERNAME_RETYPE': True,
'SET_PASSWORD_RETYPE': True,
'PASSWORD_RESET_CONFIRM_URL': 'password/reset/confirm/{uid}/{token}',
'USERNAME_RESET_CONFIRM_URL': 'email/reset/confirm/{uid}/{token}',
'ACTIVATION_URL': 'activate/{uid}/{token}',
'SEND_ACTIVATION_EMAIL': True,
'PASSWORD_RESET_CONFIRM_RETYPE': True,
'SERIALIZERS': {
'user_create': 'accounts.serializers.UserCreateSerializer',
'user': 'accounts.serializers.UserCreateSerializer',
'user_delete': 'djoser.serializers.UserDeleteSerializer',
}
}
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
AUTH_USER_MODEL = 'accounts.UserAccount'
这是一个解决方案,但必须有更好的方法来避免创建另一个 useState。
我创造了; const [image, setImage] = useState(null);
然后在输入; onChange{(e)=>setImage(e.target.files[0])}
我认为可能有一种方法可以在我的代码中将 (e.target.files[0])) 与 passport_photo 一起使用,那会很棒。
我正在使用 React 前端通过 axios 与 Django 后端进行通信。出于某种原因,我无法 post 形成包含图像的表格。我通过 Postman 测试了我的 django 后端,它运行良好。
后端在终端显示code 200为成功但未保存数据,前端未通过错误
如果我排除了图像,表单可以 post 成功。请检查下面我的代码;
form.js 文件
import React, { useState } from 'react';
import { Helmet } from 'react-helmet';
import axios from 'axios';
import { connect } from 'react-redux';
import { setAlert } from '../actions/alert';
import './ApplicationForm.css';
import { useNavigate } from 'react-router-dom';
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { IconButton } from '@mui/material';
function ApplicationForm({ setAlert }) {
const [show, setShow] = useState (false);
const navigate=useNavigate();
const [formData, setFormData] = useState({
pasport_number: '', first_name: '', last_name: '', passport_photo: ''
});
const { pasport_number, first_name, last_name, passport_photo } = formData;
const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value });
console.log (formData)
const onSubmit = e => {
e.preventDefault();
const config = {
headers: {
'Content-Type': 'application/json'
}
};
axios.post(`${process.env.REACT_APP_API_URL}/api/application-form/`, { pasport_number, first_name, last_name, passport_photo }, config)
.then(_res => {
navigate('/');
setAlert('Application Submitted Successfully', 'success');
})
.catch(_err => {
setAlert('Error with Sending Application', 'error');
})
};
return (
<div className='applicationForm'>
<div className='wrapper'>
<Helmet>
<title>Prosperity - Visa Application Form</title>
<meta
name='description'
content='Filling Application Form '
/>
</Helmet>
<div className='applicationForm__wrapper'>
<h1 className='applicationForm__title'>Application Form</h1>
<hr className='appform__hr'/>
<form className='applicationForm__form' onSubmit={e => onSubmit(e)}>
<div className='form__wrap'>
<hr className='appform__hr'/>
<p className='passport__section__title'>Enter or Import Passport Details</p>
<div className='input_grp'>
<div className='input_wrap input_wrap__bt'>
<p className='expand__p'>Enter Passport details</p>
<IconButton onClick={()=> setShow(true)}>
<ExpandMoreIcon className='Expand__bt'/>
</IconButton>
<IconButton onClick={()=> setShow(false)}>
<ExpandLessIcon className='Expand__less__bt'/>
</IconButton>
</div>
<div className='input_wrap input_wrap__bt import__passport'>
<label className='applicationForm__form__label' htmlFor='passport_photo'>Import Passport Image</label>
<input
className='input__for__two import__passport'
name='passport_photo'
type='file'
accept='image/*,.pdf'
placeholder='Import Passport'
onChange={e => onChange(e)}
value={passport_photo}
required
/>
</div>
</div>
{ show?
<>
<div className='input_grp'>
<div className='input_wrap'>
<label className='applicationForm__form__label appForm__subject' htmlFor='first_name'>First Name</label>
<input
className='applicationForm__form__input input__for__two'
name='first_name'
type='text'
placeholder='First Name *'
onChange={e => onChange(e)}
value={first_name}
required
/>
</div>
<div className='input_wrap'>
<label className='applicationForm__form__label' htmlFor='last_name'>Last Name</label>
<input
className='applicationForm__form__input input__for__two'
name='last_name'
type='text'
placeholder='Last Name *'
onChange={e => onChange(e)}
value={last_name}
required
/>
</div>
</div>
<div className='input_grp'>
<div className='form__wrap'>
<label className='applicationForm__form__label' htmlFor='pasport_number'>Passport Number</label>
<input
className='applicationForm__form__input input__for__two'
name='pasport_number'
type='text'
placeholder='Passport Number'
onChange={e => onChange(e)}
value={pasport_number}
required
/>
</div>
</div>
</>
:null
}
<hr className='appform__hr'/>
<button className='contact__form__button' htmltype='submit'>Send</button>
</div>
</form>
</div>
</div>
</div>
)
}
export default connect(null, { setAlert })(ApplicationForm);
console.log(表格数据);
{pasport_number: 'test3', first_name: 'test1', last_name: 'test2', passport_photo: 'C:\fakepath\signature.jpg'}
first_name: "test1"
last_name: "test2"
pasport_number: "test3"
passport_photo: "C:\fakepath\signature.jpg"
[[Prototype]]: Object
更新的形式包括 react-file-base64 ;
import React, { useState } from 'react';
import { Helmet } from 'react-helmet';
import axios from 'axios';
import { connect } from 'react-redux';
import { setAlert } from '../actions/alert';
import './ApplicationForm.css';
import { useNavigate } from 'react-router-dom';
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { IconButton } from '@mui/material';
import FileBase from "react-file-base64";
function ApplicationForm({ setAlert }) {
const [show, setShow] = useState (false);
const navigate=useNavigate();
const [formData, setFormData] = useState({
pasport_number: '', passport_photo: ''
});
const { pasport_number, passport_photo } = formData;
const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value });
console.log (formData);
const onSubmit = e => {
e.preventDefault();
const config = {
headers: {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json'
}
};
axios.post(`${process.env.REACT_APP_API_URL}/api/application-form/`, { pasport_number, passport_photo }, config)
.then(_res => {
setAlert('Application Submitted Successfully', 'success');
})
.catch(_err => {
setAlert('Error with Sending Application', 'error');
})
};
return (
<div className='applicationForm'>
<div className='wrapper'>
<Helmet>
<title>Prosperity - Visa Application Form</title>
<meta
name='description'
content='Filling Application Form '
/>
</Helmet>
<div className='applicationForm__wrapper'>
<h1 className='applicationForm__title'>Application Form</h1>
<hr className='appform__hr'/>
<form className='applicationForm__form' onSubmit={e => onSubmit(e)} enctype="multipart/form-data">
<div className='form__wrap'>
<hr className='appform__hr'/>
<p className='passport__section__title'>Enter or Import Passport Details</p>
<div className='input_grp'>
<div className='input_wrap input_wrap__bt'>
<p className='expand__p'>Enter Passport details</p>
<IconButton onClick={()=> setShow(true)}>
<ExpandMoreIcon className='Expand__bt'/>
</IconButton>
<IconButton onClick={()=> setShow(false)}>
<ExpandLessIcon className='Expand__less__bt'/>
</IconButton>
</div>
<FileBase
type="file"
multiple={false}
onDone={({ base64 }) =>
setFormData({ ...formData, passport_photo: base64 })}
/>
</div>
{ show?
<>
<div className='input_grp'>
<div className='form__wrap'>
<label className='applicationForm__form__label' htmlFor='pasport_number'>Passport Number</label>
<input
className='applicationForm__form__input input__for__two'
name='pasport_number'
type='text'
placeholder='Passport Number'
onChange={e => onChange(e)}
value={pasport_number}
required
/>
</div>
</div>
</>
:null
}
<hr className='appform__hr'/>
<button className='contact__form__button' htmltype='submit'>Send</button>
</div>
</form>
</div>
</div>
</div>
)
}
export default connect(null, { setAlert })(ApplicationForm);
已更新 console.log ;
{pasport_number: 'TEST99', passport_photo: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB4sA…LzzTqZ8wa/uf//J//+/8PoXjMydjnS20AAAAASUVORK5CYII='}
pasport_number: "TEST99"
passport_photo: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB4s
[[Prototype]]: Object
django settings.py ;
from datetime import timedelta
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = 'xxx'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'accounts.apps.AccountsConfig',
'application_form.apps.ApplicationFormConfig',
'social.apps.SocialConfig',
'contacts.apps.ContactsConfig',
'rest_framework',
'djoser',
'corsheaders',
'rest_framework_simplejwt.token_blacklist'
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'pros.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'build')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'prosperity.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'prosdb',
'USER': 'postgres',
'PASSWORD': 'xxxxx',
'HOST': 'localhost'
}
}
# email addition
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.xxxx.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'xxx@xxx.xx'
EMAIL_HOST_PASSWORD = 'xxxxx'
EMAIL_USE_TLS = True
MAIL_FROM_ADDRESS='xxxxxx'
# Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/
LANGUAGE_CODE = 'en-GB'
TIME_ZONE = 'CET'
DATE_INPUT_FORMATS = [
'%d-%m-%Y', '%Y-%m-%d',
'%m/%d/%Y', '%m/%d/%y',
'%b %d %Y', '%b %d, %Y',
'%d %b %Y', '%d %b, %Y',
'%B %d %Y', '%B %d, %Y',
'%d %B %Y', '%d %B, %Y',
]
USE_I18N = True
USE_TZ = True
DATA_UPLOAD_MAX_NUMBER_FIELDS = None
STATIC_URL = 'static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'build/static')
]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated'
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.MultiPartParser'
],
}
CORS_ORIGIN_ALLOW_ALL = True
FILE_UPLOAD_PERMISSIONS=0o640
# Token settings
SIMPLE_JWT = {
'AUTH_HEADER_TYPES': ('JWT',),
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'AUTH_TOKEN_CLASSES': (
'rest_framework_simplejwt.tokens.AccessToken',
)
}
DJOSER = {
'LOGIN_FIELD':'email',
'USER_CREATE_PASSWORD_RETYPE': True,
'USERNAME_CHANGED_EMAIL_CONFIRMATION': True,
'PASSWORD_CHANGED_EMAIL_CONFIRMATION': True,
'SEND_CONFIRMATION_EMAIL': True,
'SET_USERNAME_RETYPE': True,
'SET_PASSWORD_RETYPE': True,
'PASSWORD_RESET_CONFIRM_URL': 'password/reset/confirm/{uid}/{token}',
'USERNAME_RESET_CONFIRM_URL': 'email/reset/confirm/{uid}/{token}',
'ACTIVATION_URL': 'activate/{uid}/{token}',
'SEND_ACTIVATION_EMAIL': True,
'PASSWORD_RESET_CONFIRM_RETYPE': True,
'SERIALIZERS': {
'user_create': 'accounts.serializers.UserCreateSerializer',
'user': 'accounts.serializers.UserCreateSerializer',
'user_delete': 'djoser.serializers.UserDeleteSerializer',
}
}
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
AUTH_USER_MODEL = 'accounts.UserAccount'
这是一个解决方案,但必须有更好的方法来避免创建另一个 useState。
我创造了; const [image, setImage] = useState(null);
然后在输入; onChange{(e)=>setImage(e.target.files[0])}
我认为可能有一种方法可以在我的代码中将 (e.target.files[0])) 与 passport_photo 一起使用,那会很棒。