Код заставляет пользователя изменить изображение даже тогда, когда он хочет изменить только другие свойства своей статьи.

Привет всем, у меня есть блог-платформа, пользователь может добавлять и редактировать блог. Я использовал Django и Django Rest Framework для создания веб-сайта и ReactJS для внешнего интерфейса. Моя проблема в том, что когда я редактирую блог, я не могу сохранить изменения, пока не изменю изображение. Этот — это ошибка, когда я просто обновляю заголовок без изменения изображения.

модели.py

def upload_path(instance, filename):
   return 'img/{filename}'.format(filename=filename)

class Blog(models.Model):
   title = models.CharField(max_length=250)
   slug = models.SlugField(max_length=250, unique=True, null=True)
   content = models.TextField()
   published = models.DateTimeField(default=timezone.now)
   author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='blog_blog')

   objects = models.Manager()  # default manager
   image = models.ImageField(_("Image"), upload_to=upload_path, null=True)

   class Meta:
      def __str__(self):
         return self.title

просмотры.py

class EditBlog(generics.UpdateAPIView):
   permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly]
   serializer_class = BlogSerializer
   queryset = Blog.objects.all()

в React edit.js

import React, { useState, useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import axiosInstance from '../../../axios';
import WriteCss from '../../../assets/CSSStyle/WriteBlog.module.css';
import { Image } from 'antd';



export function Edit() {

const navigate = useNavigate();
const { id } = useParams();
const initialFormData = Object.freeze({
    title: '',
    slug: '',
    content: '',
});

const [formData, updateFormData] = useState(initialFormData);

const [postimage, setPostImage] = useState(null);


useEffect(() => {
    axiosInstance.get('admin/edit/postdetail/' + id).then((res) => {
        updateFormData({
            ...formData,
            ['title']: res.data.title,
            ['slug']: res.data.slug,
            ['content']: res.data.content,
            ['image']: res.data.image,

        });
    });
}, [updateFormData]);

const handleChange = (e) => {
    if ([e.target.name] == 'image') {
        setPostImage({
            image: e.target.files,
        });
        console.log("d",e.target.files);
    } 
    else {
        updateFormData({
            ...formData,
            [e.target.name]: e.target.value,
        });
    }
}

const handleSubmit = (e) => {
    e.preventDefault();
    console.log(formData);

    let ss = new FormData();
    ss.append('title', formData.title);
    ss.append('slug', formData.slug);
    ss.append('content', formData.content);
    ss.append('image', postimage.image[0]);

    axiosInstance.patch(`admin/edit/`+ id + '/', ss,  {
        headers:{
            Authorization: `JWT ${localStorage.getItem('refresh_token')}`
    },
    },)
    .then((res) => {
        // navigate('/admin/');
    });
    
};

return (
<>
<div className='container' style={{marginTop:"7.5rem"}}>
<h1 className={WriteCss.h}>Update Your Article</h1>
    <form>
        <div className='row'>
            <div className='col-12 col-md-12 col-lg-12'>
                <input
                    className={WriteCss.writeInput}
                    placeholder="Type your title ..."
                    type="text"
                    autoFocus={true}
                    id="title"
                    label="Post Title"
                    name="title"
                    autoComplete="title"
                    value={formData.title}
                    onChange={handleChange}
                />
                <input
                    className={WriteCss.writeInput}
                    placeholder="slug will be generated based on title"
                    id="slug"
                    label="Post slug"
                    name="slug"
                    autoComplete="slug"
                    value={formData.slug}
                    onChange={handleChange}
                />
            </div>
            <div className='row'>
                <div className='col-12 col-md-12 col-lg-12'>
                    <textarea
                        className={WriteCss.writeText}
                        placeholder="Type your blog..."
                        type="text"
                        id="content"
                        label="content"
                        name="content"
                        autoComplete="content"
                        value={formData.content}
                        onChange={handleChange}
                        />
                </div>
            </div>
            <Image
                src={formData.image}
                style={{ width: '200px', height: '200px' }}/>
            <input
                accept="image/*"
                id="post-image"
                onChange={handleChange}
                name="image"
                type="file"/>
            <div className='row'>
                <div className={`col-12 col-md-12 col-lg-12 ${WriteCss.col}`}>
                <button className={WriteCss.writeSubmit} type="submit" onClick={handleSubmit}>
                    Update
                </button>
                </div>
             </div>
          </div>
        </form>
      </div>
    </>
   )}

 export default Edit

Любой совет или руководство будет очень полезным для меня, чтобы завершить проект, потому что я застрял в нем более двух недель.

Спасибо

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
0
31
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема с handleSubmit, вы не можете прочитать значение postimage, если оно равно нулю:

const handleSubmit = (e) => {
    e.preventDefault();
    console.log(formData);

    let ss = new FormData();
    ss.append('title', formData.title);
    ss.append('slug', formData.slug);
    ss.append('content', formData.content);

    if (postimage != null) {
       ss.append('image', postimage.image[0]);
    }

    axiosInstance.patch(`admin/edit/`+ id + '/', ss,  {
        headers:{
            Authorization: `JWT ${localStorage.getItem('refresh_token')}`
    },
    },)
    .then((res) => {
        // navigate('/admin/');
    });
    
};

Не забудьте установить required=False для image поля BlogSerializer.

Однако я не уверен, почему я должен указывать (required=False для поля изображения BlogSerializer), когда я уже написал в models.py image = models.ImageField(_("Image"), upload_to=upload_path, null= True) недостаточно null=True?

shahid 10.04.2022 02:01

@shahid Вы не предоставляете код своего BlogSerializer, я не знаю, как вы его пишете, поэтому не могу ответить. Попробуйте без, и если это работает, оставьте его

RedWheelbarrow 10.04.2022 13:08

Приношу извинения за то, что забыл включить BlogSerializer. class BlogSerializer(serializers.ModelSerializer): автор = StringRelatedField() class Meta: fields = ('id', 'title', 'slug', 'опубликовано', 'автор', 'контент', 'изображение') model = Blog ,,,Но теперь код работает без ошибок, большое спасибо за помощь. <3

shahid 10.04.2022 13:36

Другие вопросы по теме