django 为一个帖子添加多个类别(drf+React)

6yjfywim  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(126)

我有一个使用Django和React构建的博客网站。我目前正在添加一个新的博客文章功能,我希望允许用户为他们的博客文章选择一个或多个类别。以下是我到目前为止所做的工作:
1.从数据库中获取所有类别,并将其显示在一个可选/选择字段中。
1.用户可以从目录中选择一个或多个类别。
现在,我需要帮助的下一个步骤.我如何才能发送选定的类别到数据库和保存他们的新博客文章?任何指导或代码示例将不胜感激.

import React, { useEffect, useState } from 'react';
import Dashboard from './Dashboard';
import useAxios from '../../utils/useAxios';
function AuthorCreateBlogs() {
    const baseurl = "http://127.0.0.1:8000/api/posts/v1";
    const [selectedCategories, setSelectedCategories] = useState([]);
    const api = useAxios();
    const [categoriesData, setCategoriesData] = useState([]);
    const [blogData, setBlogData] = useState({
        "title": "",
        "slug": "",
        "body": "",
        "tags": "",
        "categories": [],
        "img": "",
    })

    const handelInputChange = (event) => {
        const { name, value } = event.target;
        setBlogData((blogData) => ({
            ...blogData,
            [name]: value
        }));
    };
    const handleFileChange = (event) => {
        setBlogData((blogData) => ({
            ...blogData,
            ['img']: event.target.files[0] // Match the key used in FormData
        }));
    };

    const handleSubmit = (e) => {
        e.preventDefault();
        const form = {
            'title': blogData.title,
            'slug': blogData.slug,
            'body': blogData.body,
            'tags': blogData.tags,
            'img': blogData.img,
            'categories': blogData.categories,
            'status': document.getElementById('status2').checked

        }
        console.log(form);
        api.post(baseurl + '/author/posts/', form, {
            headers: { "Content-Type": "multipart/form-data" },
        })
            .then(response => {
                console.log('Post created:', response.data);
            })
            .catch(error => {
                console.error('Error creating post:', error);
            });

        setBlogData({

            "title": "",
            "slug": "",
            "body": "",
            "tags": "",
            "categories": "",
            "img": "",
        })
    };

    useEffect(() => {
        api.get(baseurl + '/categories/') // Adjust the URL to your actual category endpoint
            .then(response => {
                setCategoriesData(response.data);
            })
            .catch(error => {
                console.error('Error fetching categories:', error);
            });
    }, []);


    return (
        <div className='grid grid-cols-3 bg-gray-300'>
            <div className='col-span-1'>
                <Dashboard />
            </div>
            <div className='col-span-2 mr-24 mt-16'>
                <div className="lg:ms-auto mx-auto text-center">
                    <div className="py-16 px-7 rounded-md bg-white">
                        <form action="" onSubmit={handleSubmit}>
                            <div className="grid md:grid-cols-2 grid-cols-1 gap-6">
                                <input
                                    type="text"
                                    id="fname"
                                    name="title"
                                    placeholder="Title"
                                    value={blogData.title}
                                    onChange={handelInputChange}
                                    className="w-full border border-gray-300 rounded-md py-2 px-3 focus:outline-none focus:border-blue-700"
                                />
                                <input
                                    type="text"
                                    id="fname"
                                    name="slug"
                                    placeholder="Slug"
                                    value={blogData.slug}
                                    onChange={handelInputChange}
                                    className="w-full border border-gray-300 rounded-md py-2 px-3 focus:outline-none focus:border-blue-700"
                                />

                                <div className="md:col-span-2">
                                    <label htmlFor="categories" className="float-left block font-normal text-gray-400 text-lg">
                                        Categories:
                                    </label>
                                    <select
                                        id="subject"
                                        name="categories"
                                        
                                        onChange={handelInputChange}
                                        className="w-full border border-gray-300 rounded-md py-2 px-3 focus:outline-none focus:border-blue-700"
                                    >
                                        <option value="" disabled selected>
                                            Choose category:
                                        </option>
                                        {categoriesData?.map((category) => {
                                            return (

                                                <option key={category.id} value={category.id}>
                                                    {category.name}
                                                </option>

                                            )
                                        })}
                                    </select>
                                </div>

                                <div className="md:col-span-2">
                                    <label htmlFor="file" className="float-left block font-normal text-gray-400 text-lg">
                                        Image:
                                    </label>
                                    <input
                                        type="file"
                                        name='img' // Match the key in FormData
                                        onChange={handleFileChange}
                                        id="ProfileImage"
                                        aria-describedby="emailHelp"
                                        className="peer block w-full appearance-none border-none bg-transparent py-2.5 px-0 text-sm text-gray-900 focus:border-blue-600 focus:outline-none focus:ring-0"
                                    />

                                </div>
                                <div className="md:col-span-2">
                                    <label htmlFor="status2" className="float-left block font-normal text-gray-400 text-lg">
                                        Status:
                                    </label>
                                    <input
                                        type="checkbox"
                                        id="status2"
                                        name="file"
                                        className='transform scale-150'
                                    />
                                </div>

                                <div className="md:col-span-2">
                                    <label htmlFor="subject" className="float-left block font-normal text-gray-400 text-lg">
                                        Body:
                                    </label>
                                    <textarea
                                        name="body"
                                        rows="5"
                                        cols=""
                                        placeholder="Body..."
                                        value={blogData.body}
                                        onChange={handelInputChange}
                                        className="w-full border border-gray-300 rounded-md py-2 px-3 focus:outline-none focus:border-blue-700"
                                    ></textarea>
                                </div>
                                <div className="md:col-span-2">
                                    <textarea
                                        name="tags"
                                        rows="5"
                                        cols=""
                                        placeholder="Tags, please separate with ,"
                                        value={blogData.tags}
                                        onChange={handelInputChange}
                                        className="w-full border border-gray-300 rounded-md py-2 px-3 focus:outline-none focus:border-blue-700"
                                    ></textarea>
                                </div>
                                <div className="md:col-span-2">
                                    <button className="py-3 text-base font-medium rounded text-white bg-blue-800 w-full hover:bg-blue-700 transition duration-300">
                                        Valider
                                    </button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    );
}

export default AuthorCreateBlogs;

字符串
我可以选择一个类别,并将其发送到数据库,并成功创建一个职位,但我希望用户能够选择多个项目。

zi8p0yeb

zi8p0yeb1#

有多种方法可以做到这一点;
1.你可以使用像Antdesign这样的库,它带有一些非常好的multiselect功能。这里有一个指向ant design的multiselect输入的链接[https://ant.design/components/select][1],这里是multiselect框的样子[https://ant.design/multiselemos/select-demo-big-data][2]。这里是上面multiselect输入的JavaScript代码片段。

import React from 'react';
import { Select, Typography } from 'antd';
const { Title } = Typography;
const options = [];
for (let i = 0; i < 100000; i++) {
  const value = `${i.toString(36)}${i}`;
  options.push({
    label: value,
    value,
    disabled: i === 10,
  });
}
const handleChange = (value) => {
  console.log(`selected ${value}`);
};
const App = () => (
  <>
    <Title level={4}>{options.length} Items</Title>
    <Select
      mode="multiple"
      style={{
        width: '100%',
      }}
      placeholder="Please select"
      defaultValue={['a10', 'c12']}
      onChange={handleChange}
      options={options}
    />
  </>
);
export default App;

字符串
1.也可以像这样将multiple属性添加到select标记中

<select
        id="subject"
        name="categories"
        onChange={handelInputChange}
        className="w-full border border-gray-300 rounded-md py-2 px-3 focus:outline-none focus:border-blue-700"
        multiple // Added the multiple attribute here
    >


但是我认为你的handelInputChange函数在select输入上不允许接受多个选项,因为你的函数在这里设置了BlogData。

setBlogData((blogData) => ({
            ...blogData,
            [name]: value
        }));


正在用新的值替换旧的值。也许可以为select输入创建一个新的处理程序

const handelSelectInputChange = (event) => {
        const { name, value } = event.target;
    setBlogData((blogData) => ({
                ...blogData,
                categories: value + old_value
            }));
        
    };


因此,每个新的选择不会取代旧的选择。

相关问题