#reactjs #django #django-models #django-rest-framework #react-select
#reactjs #django #django-модели #django-rest-framework #реагировать-выбрать
Вопрос:
У меня есть веб-страница в моем проекте отслеживания проблем, которая позволяет менеджеру проекта назначать пользователя проекту. Я использую React Select, чтобы позволить менеджеру выбирать пользователя из выпадающего списка. Когда они нажимают кнопку «Добавить пользователя», выбранное значение отправляется на серверную часть через вызов api. У меня есть APIView с именем assignuser, который принимает post-запрос и обновляет поле внешнего ключа пользователя в моей модели проекта.
Я неправильно ссылаюсь на выбранное значение? Я попытался отправить SelectedValue.значение для моего бэкэнда, но оно продолжает отображаться как неопределенное. Имейте в виду, очевидно, при консоли.оба значения журнала SelectedValue {label: "...", value: "..."}
находятся в SelectedValue. Это также относится к SV в project.js это отправляется в manageusers.js . Я просто пытаюсь ссылаться на значение и успешно отправлять его в мой APIView и обновлять пользователя конкретного проекта.
Серверная часть Django
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 amp;amp; 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 amp;amp; 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;
Модель проекта
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)
Ответ №1:
вы можете сделать это
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)
});
или вы можете добавить новое значение без использования серверной части для получения новых данных,
почему я даю эту опцию, когда вы отправляете данные на серверную часть, они автоматически сохраняются для этого пользователя, и когда пользователь перезагружает значение страницы, которая выйдет, остается прежним
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 amp;amp; 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;
Комментарии:
1. что делает validated_data?
2. Итак, я пытаюсь взять выбранное значение из моего интерфейса, отправить его назначающему пользователю и установить внешний ключ с именем user в моей модели проекта с этим выбранным значением. Этот код, который у вас есть, только что получает последний проект в наборе запросов и возвращает его.
3. по-прежнему безуспешно, я внес правку выше, чтобы уточнить, о чем я говорил
4. может быть, вы имеете в виду, что когда пользователь нажимает кнопку, она автоматически появляется в выпадающем списке?
5. может быть , вот так