【发布时间】:2021-08-02 07:42:37
【问题描述】:
我正在关注关于 Django API 的简短教程,其中我扩展了模型以包含更多字段
我可以让前端工作,但不能为新字段发布数据
下面的代码块是我想在帖子中添加更多字段的地方...,至少我认为应该去的地方...??
var title = document.getElementById('title').value
fetch(url, {
method:'POST',
headers:{
'Content-type':'application/json',
'X-CSRFToken':csrftoken,
},
body: JSON.stringify({'title': title
})
}
).then(function(response){
buildList()
document.getElementById('form').reset()
})
})
**** 型号****
from django.db import models
# Create your models here.
class Task(models.Model):
title = models.CharField(max_length=200)
completed = models.BooleanField(default=False, blank=True, null=True)
name = models.CharField(max_length=75, blank=True, null=True)
price = models.FloatField(default='0.00')
productdesc = models.CharField(db_column='ProductDesc', max_length=75, blank=True, null=True) # Field name made lowercase.
producttype = models.CharField(db_column='ProductType', max_length=75, blank=True, null=True) # Field name made lowercase.
producttypefamily = models.CharField(db_column='ProductTypeFamily', max_length=75, blank=True, null=True) # Field name made lowercase.
numworkstation = models.IntegerField(db_column='Numworkstation', default='0') # Field name made lowercase.
numserver = models.IntegerField(db_column='Numserver', default='0') # Field name made lowercase.
addlconsole = models.IntegerField(db_column='addlconsole', default='0') # Field name made lowercase.
productcomplexitybase = models.FloatField(db_column='ProductComplexityBase', default='550') # Field name made lowercase.
productcomplexityfac = models.FloatField(db_column='ProductComplexityFac', default='1.0') # Field name made lowercase.
digital = models.BooleanField(default=False,null=True, blank=True)
def __str__(self):
***** view.py *****
from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serializers import TaskSerializer
from .models import Task
# Create your views here.
@api_view(['GET'])
def apiOverview(request):
api_urls = {
'List':'/task-list/',
'Detail View':'/task-detail/<str:pk>/',
'Create':'/task-create/',
'Update':'/task-update/<str:pk>/',
'Delete':'/task-delete/<str:pk>/',
}
return Response(api_urls)
@api_view(['GET'])
def taskList(request):
tasks = Task.objects.all().order_by('-id')
serializer = TaskSerializer(tasks, many=True)
return Response(serializer.data)
@api_view(['GET'])
def taskDetail(request, pk):
tasks = Task.objects.get(id=pk)
serializer = TaskSerializer(tasks, many=False)
return Response(serializer.data)
@api_view(['POST'])
def taskCreate(request):
serializer = TaskSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
@api_view(['POST'])
def taskUpdate(request, pk):
task = Task.objects.get(id=pk)
serializer = TaskSerializer(instance=task, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
@api_view(['DELETE'])
def taskDelete(request, pk):
task = Task.objects.get(id=pk)
task.delete()
return Response('Item succsesfully delete!')
***** list.html ****
<!DOCTYPE html>
<html>
<head>
<title>TO DO</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<style type="text/css">
body{
background: rgb(54,217,182);
background: linear-gradient(90deg, rgba(54,217,182,1) 0%, rgba(32,152,126,1) 43%, rgba(0,212,255,1) 100%);
}
h1, h2, h3, h4, h5, p, span, strike{
font-family: 'Montserrat', sans-serif;
}
#task-container{
max-width:900px;
margin:0 auto;
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22);
background-color: #fff;
margin-top:100px;
margin-bottom:100px;
justify-content: space-around;
align-items: flex-start;
}
#form-wrapper{
position: -webkit-sticky;
position: sticky;
top: 0rem;
border-bottom: 1px solid #e9e9e9;
background-color: #fff;
box-shadow: 0 3px 8px rgba(0,0,0,0.25);
padding:40px;
}
#submit{
background-color: #36d9b6;
border-radius: 0;
border:0;
color: #fff;
}
.flex-wrapper{
display: flex;
}
.task-wrapper{
margin:5px;
padding: 5px;
padding:20px;
cursor: pointer;
border-bottom: 1px solid #e9e9e9;
color: #686868;
}
</style>
</head>
<body>
<div class="container">
<div id="task-container">
<div id="form-wrapper">
<form id="form">
<div class="flex-wrapper">
<div style="flex: 6">
<input id="title" class="form-control" type="text" name="title" placeholder="Add task">
</div>
<div style="flex: 5">
<input id="numserver" class="form-control" type="text" name="numserver" placeholder="Enter # Svrs">
</div>
<div style="flex: 5">
<input id="numworkstation" class="form-control" type="text" name="numworkstation" placeholder="Enter # Wkstns">
</div>
<div style="flex: 1">
<input id="submit" class="btn" type="submit">
</div>
</div>
</form>
</div>
<div id="list-wrapper">
</div>
</div>
</div>
<script type="text/javascript">
/*
KEY COMPONENTS:
"activeItem" = null until an edit button is clicked. Will contain object of item we are editing
"list_snapshot" = Will contain previous state of list. Used for removing extra rows on list update
PROCESS:
1 - Fetch Data and build rows "buildList()"
2 - Create Item on form submit
3 - Edit Item click - Prefill form and change submit URL
4 - Delete Item - Send item id to delete URL
5 - Cross out completed task - Event handle updated item
NOTES:
-- Add event handlers to "edit", "delete", "title"
-- Render with strike through items completed
-- Remove extra data on re-render
-- CSRF Token
*/
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
var activeItem = null
var list_snapshot = []
buildList()
function buildList(){
var wrapper = document.getElementById('list-wrapper')
//wrapper.innerHTML = ''
var url = 'http://127.0.0.1:8000/api/task-list/'
fetch(url)
.then((resp) => resp.json())
.then(function(data){
console.log('Data:', data)
var list = data
for (var i in list){
try{
document.getElementById(`data-row-${i}`).remove()
}catch(err){
}
var title = `<span class="title">${list[i].title}</span>`
var numserver = `<span class="numserver">${list[i].numserver}</span>`
var numworkstation = `<span class="numworkstion">${list[i].numworkstation}</span>`
if (list[i].completed == true){
title = `<strike class="title">${list[i].title}</strike>`
numserver = `<strike class="numserver">${list[i].numserver}</strike>`
numworkstation = `<strike class="numworkstation">${list[i].numworkstation}</strike>`
}
var item = `
<div id="data-row-${i}" class="task-wrapper flex-wrapper">
<div style="flex:6">
${title}
</div>
<div style="flex:5">
${numserver}
</div>
<div style="flex:5">
${numworkstation}
</div>
<div style="flex:1">
<button class="btn btn-sm btn-outline-info edit">Edit </button>
</div>
<div style="flex:1">
<button class="btn btn-sm btn-outline-dark delete">-</button>
</div>
</div>
`
wrapper.innerHTML += item
}
if (list_snapshot.length > list.length){
for (var i = list.length; i < list_snapshot.length; i++){
document.getElementById(`data-row-${i}`).remove()
}
}
list_snapshot = list
for (var i in list){
var editBtn = document.getElementsByClassName('edit')[i]
var deleteBtn = document.getElementsByClassName('delete')[i]
var title = document.getElementsByClassName('title')[i]
//var numserver = document.getElementsByClassName('numserver')[i]
// var numworkstation = document.getElementsByClassName('numworkstation')[i]
editBtn.addEventListener('click', (function(item){
return function(){
editItem(item)
}
})(list[i]))
deleteBtn.addEventListener('click', (function(item){
return function(){
deleteItem(item)
}
})(list[i]))
title.addEventListener('click', (function(item){
return function(){
strikeUnstrike(item)
}
})(list[i]))
}
})
}
var form = document.getElementById('form-wrapper')
form.addEventListener('submit', function(e){
e.preventDefault()
console.log('Form submitted')
var url = 'http://127.0.0.1:8000/api/task-create/'
if (activeItem != null){
var url = `http://127.0.0.1:8000/api/task-update/${activeItem.id}/`
activeItem = null
}
var title = document.getElementById('title').value
fetch(url, {
method:'POST',
headers:{
'Content-type':'application/json',
'X-CSRFToken':csrftoken,
},
body: JSON.stringify({'title': title
})
}
).then(function(response){
buildList()
document.getElementById('form').reset()
})
})
function editItem(item){
console.log('Item clicked:', item)
activeItem = item
document.getElementById('title').value = activeItem.title
}
function deleteItem(item){
console.log('Delete clicked')
fetch(`http://127.0.0.1:8000/api/task-delete/${item.id}/`, {
method:'DELETE',
headers:{
'Content-type':'application/json',
'X-CSRFToken':csrftoken,
}
}).then((response) => {
buildList()
})
}
function strikeUnstrike(item){
console.log('Strike clicked')
item.completed = !item.completed
fetch(`http://127.0.0.1:8000/api/task-update/${item.id}/`, {
method:'POST',
headers:{
'Content-type':'application/json',
'X-CSRFToken':csrftoken,
},
body:JSON.stringify({'title':item.title, 'completed':item.completed})
}).then((response) => {
buildList()
})
}
</script>
</body>
</html>
【问题讨论】:
标签: json django serialization