Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
373 views
in Technique[技术] by (71.8m points)

reactjs - Django foreign key field not updating with selected value from React Select dropdown

I have a webpage in my issue tracker project that allows a project manager to assign a user to a project. I am using React Select to allow the manager to select a user from a dropdown. When they click the add user button, the selected value gets sent to the backend through an api call. I have an APIView called assignuser, which takes in the post request and updates the user foreign key field in my Project model.

Am I referencing the selected value wrong? I have tried sending selectedValue.value to my backend but it keeps on coming up as undefined. Keep in mind, obviously when you console.log selectedValue {label: "...", value: "..."} are both in selectedValue. This also applies to the SV in project.js that gets sent to manageusers.js. I'm just trying to reference value & send it to my APIView successfully and update the user of a particular project.

project.js

manageusers.js

Django Backend

class assignuser(APIView):
    serializer_class = ProjectSerializer

    def post(self, request, format=None):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            user = serializer.data.get('user')
            project_name = serializer.data.get('project_name')
            project = Project.objects.get(name=project_name)
            project.user = user
            project.save(update_fields=['user'])
            return Response(ProjectSerializer(project).data, status=status.HTTP_201_CREATED)
        else:
            return HttpResponse("Incorrect Credentials")

manageusers.js

import React, { Component } from "react";
import { useState, useEffect } from "react";
import { Grid, TextField, Button, Typography } from "@material-ui/core";
import { FixedSizeList as List } from 'react-window';
import css from './style.css';
import Select from 'react-select';
import {useLocation} from "react-router";

const manageusers = () => {
  const [role, setRole] = useState([]);
  const location = useLocation();
  const [project_name, setProjectName] = useState();
  const [selectedValue, setSelectedValue] = useState()
  const rolelist = [];

  const handleChange = obj => {
      setSelectedValue(obj);
  }

  useEffect(() => {
    fetch("/api/manageroles")
    .then((response) => response.json())
    .then((data) =>{
        setRole(data)
    })
  }, [])

  const post = () => {
    const requestOptions = {
      method: "POST",
      headers: { "Content-Type": "application/json"},
      body: JSON.stringify({
        user: selectedValue,
        project_name: project_name
      }),
    };
    fetch("/api/assignuser",requestOptions)
      .then((response) => response.text())
      .then((data) =>{
       
      })
      .catch((error) => {
        console.log(error)
      });
  }

  const Name = () => {
      return (
        <div>
            <Grid item xs={3}>
                <Typography component="h5" variant="h5">
                    {setProjectName(location.state.project_name)}
                </Typography>
            </Grid>  
        </div>
      )
    
  }

      return (
          <div>  
            {role.forEach(function(element) {
                rolelist.push({ label:element.username, value: element.username })
            })}
            <Select
                value={selectedValue}
                options={rolelist}
                onChange={handleChange}
                isOptionDisabled={option => option.isDisabled}
            />
            <div class="ex1">
                {role && role.map(roles => (
                        <Grid item xs={3}>
                            <Typography component="h5" variant="h5">
                                <h5> {roles.username} </h5>
                            </Typography>
                        </Grid>
                ))}
            </div>
            <div>
                <Button onClick={() => post()}> Add User</Button>
            </div>
            <Name/>
        </div>
      );
      
  }

export default manageusers;

project.js

import React, { Component } from "react";
import { useState, useEffect } from "react";
import { Grid, TextField, Button, Typography } from "@material-ui/core";
import {
    BrowserRouter as Router,
    Link,
    Route,
    Switch,
  } from 'react-router-dom';
import Select from 'react-select';

const project = () => {
  const [name, setName] = useState();
  const [description, setDescription] = useState();
  const [projects, setProjects] = useState([]);
  const [selectedValue, setSelectedValue] = useState(null)
  const projectlist = [];
  
  const handleChange = obj => {
      setSelectedValue(obj);
  }

  const post = () => {
    const requestOptions = {
      method: "POST",
      headers: { "Content-Type": "application/json"},
      body: JSON.stringify({
        name: name,  
        description: description,
      }),
    };
    fetch("/api/newProject",requestOptions)
      .then((response) => response.json())
      .then((data) =>{
       
      })
  }

  useEffect(() => {
    fetch("/api/manageprojects")
    .then((response) => response.json())
    .then((data) =>{
        setProjects(data)
    })
  }, [])

      return (
        <div>
           {projects.forEach(function(element) {
                projectlist.push({ value: element.name })
            })}
          <body>
            <Select 
                  value={selectedValue}
                  options={projectlist}
                  onChange={handleChange}
                  isOptionDisabled={option => option.isDisabled}
              />
              <form action="#" method="POST">
                <TextField onChange={(e) => setName(e.target.value)}> </TextField>
                <br>
                </br>
                <TextField onChange={(e) => setDescription(e.target.value)}> </TextField>
                <br>
                </br>
                <Button onClick={() => post()}> Create New Project </Button>
              </form>
          </body>
          <div>
                {projects && projects.map(project => (
                    <Grid item xs={3}>
                        <Typography component="h5" variant="h5">
                            <h5> {project.name} </h5>
                            <h5> {project.description} </h5>
                        </Typography>
                    </Grid>
                ))}
          </div>
          <Link to={{
            pathname: '/manageusers',
            state: { 
                project_name: selectedValue
            }
          }}>Manage Users
          </Link>
        </div>
      );
  }
 


export default project;

Project Model

class Project(models.Model):
    name = models.CharField(max_length=50, unique=True)
    description = models.CharField(max_length=50, unique=True)
    user = models.ForeignKey(Users, null=True, blank=True, 
    on_delete=models.CASCADE)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

you can do this

class assignuser(APIView):
    serializer_class = ProjectSerializer

    def post(self, request, format=None):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            project = serializer.validated_data.get("project_name")
            project.user = serializer.validated_data.get("user")
            project.save()
            return Response(ProjectSerializer(project).data, status=status.HTTP_201_CREATED)
        else:
            return HttpResponse("Incorrect Credentials")
fetch("/api/assignuser",requestOptions)
      .then((response) => response.text())
      .then((data) =>{
         setRole([...role, data])    
      })
      .catch((error) => {
        console.log(error)
      });

or you can add new value without from backend for get new data,

why do I give this option, when you send data to the backend it will automatically be saved for that user and when the user reloads the value of the page that will come out remains the same

  const post = () => {
    const requestOptions = {
      method: "POST",
      headers: { "Content-Type": "application/json"},
      body: JSON.stringify({
        user: selectedValue,
        project_name: project_name
      }),
    };
    fetch("/api/assignuser",requestOptions)
      .then((response) => response.text())
      .then((data) =>{
        setRole([...role, {label: project_name, value: project_name}])
      })
      .catch((error) => {
        console.log(error)
      });
  }

base.js

const Base = () => {
  const [selectedValue, setSelectedValue] = React.useState()
  return (
    <div>
       <ManagerUser selectedValue={selectedValue} setProjectName={setSelectedValue}/>
       <Project selectedValue={selectedValue} setProjectName={setSelectedValue}/>
   </div>
  )
}

project.js

import React, { Component } from "react";
import { useState, useEffect } from "react";
import { Grid, TextField, Button, Typography } from "@material-ui/core";
import {
    BrowserRouter as Router,
    Link,
    Route,
    Switch,
  } from 'react-router-dom';
import Select from 'react-select';

const project = (props) => {
  const {selectedValue,setSelectedValue} = props
  const [name, setName] = useState();
  const [description, setDescription] = useState();
  const [projects, setProjects] = useState([]);
  const projectlist = [];
  
  const handleChange = obj => {
      setSelectedValue(obj);
  }

  const post = () => {
    const requestOptions = {
      method: "POST",
      headers: { "Content-Type": "application/json"},
      body: JSON.stringify({
        name: name,  
        description: description,
      }),
    };
    fetch("/api/newProject",requestOptions)
      .then((response) => response.json())
      .then((data) =>{
       
      })
  }

  useEffect(() => {
    fetch("/api/manageprojects")
    .then((response) => response.json())
    .then((data) =>{
        setProjects(data)
    })
  }, [])

      return (
        <div>
           {projects.forEach(function(element) {
                projectlist.push({ value: element.name })
            })}
          <body>
            <Select 
                  value={selectedValue}
                  options={projectlist}
                  onChange={handleChange}
                  isOptionDisabled={option => option.isDisabled}
              />
              <form action="#" method="POST">
                <TextField onChange={(e) => setName(e.target.value)}> </TextField>
                <br>
                </br>
                <TextField onChange={(e) => setDescription(e.target.value)}> </TextField>
                <br>
                </br>
                <Button onClick={() => post()}> Create New Project </Button>
              </form>
          </body>
          <div>
                {projects && projects.map(project => (
                    <Grid item xs={3}>
                        <Typography component="h5" variant="h5">
                            <h5> {project.name} </h5>
                            <h5> {project.description} </h5>
                        </Typography>
                    </Grid>
                ))}
          </div>
          <Link to={{
            pathname: '/manageusers',
            state: { 
                project_name: selectedValue
            }
          }}>Manage Users
          </Link>
        </div>
      );
  }
 


export default project;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...