Dear Sirs,
With proper readUrl configuration in ajaxstore, the backend django rest framework datasets can be display in grid component now.
However, while I update the first record country column from "U.S." to "U.S.A.", the update action is failed with status 400 bad request.
I'm not quite sure whether it is happend at the backend django rest framework or the frontend bryntum process the response.
See below the error message in detail:
Failed to load resource: the server responded with a status of 400 (Bad Request)
action
:
"commit"
changes
:
added
:
Array(0)
length
:
0
[[Prototype]]
:
Array(0)
modified
:
Array(1)
0
:
e
data
:
{id: '3', country: 'U.S.A.', population: 326766748, yearlychange: 0.0071, netchange: 2307285, …}
response
:
Response
parsedJson
:
country
:
Array(1)
0
:
"This field is required."
length
:
1
update
:
action
:
"update"
body
:
data
:
Array(1)
0
:
{country: 'U.S.A.', id: '3'}
error
:
TypeError: Cannot read properties of undefined (reading 'forEach') at AjaxStore.processReturnedData (http://127.0.0.1:8000/static/js/bryntum/build/grid.module.js:10:530467) at http://127.0.0.1:8000/static/js/bryntum/build/grid.module.js:10:529239
message
:
"Cannot read properties of undefined (reading 'forEach')"
stack
:
"TypeError: Cannot read properties of undefined (reading 'forEach')\n at AjaxStore.processReturnedData (http://127.0.0.1:8000/static/js/bryntum/build/grid.module.js:10:530467)\n at http://127.0.0.1:8000/static/js/bryntum/build/grid.module.js:10:529239"
[[Prototype]]
:
Error
eventName
:
"afterRequest"
exception
:
true
exceptionType
:
"server"
json
:
{country: Array(1)}
params
:
undefined
response
:
Response {parsedJson: {…}, type: 'basic', url: 'http://127.0.0.1:8000/populations/', redirected: false, status: 400, …}
source
:
AjaxStore {added: StoreBag, removed: StoreBag, modified: StoreBag, idRegister: {…}, internalIdRegister: {…}, …}
type
:
"afterrequest"
[[Prototype]]
:
Object
[[Prototype]]
:
Object
See below the code:
// bryntum_grid_rest.js
import { Grid, AjaxStore, Model } from '../../js/bryntum/build/grid.module.js';
class Population extends Model {
static fields = ['id', 'country', 'population', 'yearlychange', 'netchange', 'density', 'area', 'migrants', 'fert', 'age', 'urban' ]
}
const store = new AjaxStore({
modelClass : Population,
createUrl : "/populations/",
readUrl : "/populations/",
updateUrl : "/populations/",
deleteUrl : "/populations/",
autoLoad : true,
autoCommit : true,
});
new Grid({
appendTo : 'container',
features : {
group : false
},
// Headers will ripple on tap in Material theme
ripple : {
delegate : '.b-grid-header'
},
columns:[
{ field:"id", text:"id", width:20 },
{ field:"country", text:"country", width:100 },
{ field:"population", text:"population", width:100, type: "number" },
{ field:"yearlychange", text:"yearlyChange", width:100, type: "number" },
{ field:"netchange", text:"netChange", width:100, type: "number"},
{ field:"density", text:"density", width:80, type: "number"},
{ field:"area", text:"area", width:80, type: "number"},
{ field:"migrants", text:"migrants", width:80, type: "number"},
{ field:"fert", text:"fert", width:80, type: "number"},
{ field:"age", text:"age", width:80, type: "number"},
{ field:"urban", text:"urban", width:80, type: "number"},
],
store
});
# quickstart/models.py
from django.db import models
# Create your models here.
class Population(models.Model):
country = models.CharField(max_length=100)
population = models.IntegerField()
yearlychange = models.FloatField()
netchange = models.IntegerField()
density = models.IntegerField()
area = models.IntegerField()
migrants = models.IntegerField()
fert = models.FloatField()
age = models.IntegerField()
urban = models.FloatField()
# quickstart/serializers.py
from rest_framework import serializers
from .models import Population
class PopulationSerializer(serializers.HyperlinkedModelSerializer):
id = serializers.CharField(required=False)
country = serializers.CharField(required=True)
population = serializers.IntegerField(required=False)
yearlychange = serializers.FloatField(required=False)
netchange = serializers.IntegerField(required=False)
density = serializers.IntegerField(required=False)
area = serializers.IntegerField(required=False)
migrants = serializers.IntegerField(required=False)
fert = serializers.FloatField(required=False)
age = serializers.IntegerField(required=False)
urban = serializers.FloatField(required=False)
class Meta:
model = Population
fields = ('id', 'country', 'population', 'yearlychange', 'netchange', 'density', 'area', 'migrants', 'fert', 'age', 'urban')
# quickstart/urls.py
from django.urls import include, path
from rest_framework import routers
from quickstart import views
router = routers.DefaultRouter(trailing_slash=True)
router.register(r'populations', views.PopulationViewSet)
urlpatterns = [
]
urlpatterns += [
path('', views.index, name='index'),
]
urlpatterns += router.urls
# quickstart/views.py
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework import viewsets
from .models import Population
from quickstart.serializers import PopulationSerializer
def index(request):
return render(request, 'quickstart/indexBryntum.html')
class PopulationViewSet(viewsets.ModelViewSet):
queryset = Population.objects.all()
serializer_class = PopulationSerializer
def list(self, request):
queryset = Population.objects.all()
serializer = PopulationSerializer(queryset, many=True, context={'request': request})
return Response(serializer.data)