尝试使用Django restframework + Datatables显示表,搜索时出错

xoefb8l8  于 2023-05-08  发布在  Go
关注(0)|答案(1)|浏览(116)

我已经更新了这个问题,因为我已经能够显示数据表。
现在,我在搜索table时遇到了麻烦。
models.py:

class Sites(models.Model):
    site_id = models.IntegerField(primary_key=True)
    site_name = models.CharField(max_length=20)
    site_description = models.TextField()

    class Meta:
        managed = False
        db_table = 'sites'

views.py:

class SitesViewSet(viewsets.ModelViewSet):
    queryset = Sites.objects.all()
    serializer_class = SitesViewSerializer

    def list(self, request, **kwargs):
        try:
            query = query_sites_by_args(**request.query_params)
            serializer = SitesViewSerializer(query['items'], many=True)
            result = dict()
            result['data'] = serializer.data
            result['draw'] = query['draw']
            result['recordsTotal'] = query['total']
            result['recordsFiltered'] = query['count']
            return Response(result, status=status.HTTP_200_OK, template_name=None, content_type=None)

        except Exception as e:
            return Response(e, status=status.HTTP_404_NOT_FOUND, template_name=None, content_type=None)

serializers.py:

class SitesViewSerializer(serializers.ModelSerializer):
    class Meta:
        model = Sites
        fields = ('site_id', 'site_name', 'site_description')

javascript:

$(document).ready(function() {

    let table = $('#datatables').DataTable({
        search:{
        },
        lengthMenu: [[25, 50, 100, -1], [25, 50, 100, "All"]],
        responsive: true,
        processing: true,
        serverSide: true,
        bSearchable: true,
        ajax: {
            url: "/api/sites/",
            type: "GET"
        },
        columns: [
            {"data": "site_id"},
            {"data": "site_name"},
            {"data": "site_description"},
             // {"data": "link"},
            {
                "data": null,
                "defaultContent": '<button type="button" class="btn btn-success">View Participants</button>'

            }
        ],
    } );

    // on button click
   $('#datatables tbody').on('click', 'button', function (x) {
        let url;
        let data = table.row($(this).parents('tr')).data();
        let class_name = $(this).attr('class');

        if (class_name === 'btn btn-success') {
            // assign the full s3 path of the file to filename
            let sitename = data['site_name'];

            url = 'site' + "/" + sitename;

            location.href = url;

        }

   });
} );

这是我的完整追踪。

Internal Server Error: /api/sites/
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/django/core/handlers/base.py", line 202, in _get_response
    response = response.render()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/django/template/response.py", line 105, in render
    self.content = self.rendered_content
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/rest_framework/response.py", line 70, in rendered_content
    ret = renderer.render(self.data, accepted_media_type, context)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/rest_framework/renderers.py", line 99, in render
    ret = json.dumps(
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/rest_framework/utils/json.py", line 25, in dumps
    return json.dumps(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/rest_framework/utils/encoders.py", line 67, in default
    return super().default(obj)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type FieldError is not JSON serializable
[03/May/2023 22:46:49] "GET /api/sites/?draw=3&columns%5B0%5D%5Bdata%5D=site_id&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=site_name&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=true&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=site_description&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=true&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=asc&start=0&length=25&search%5Bvalue%5D=yay&search%5Bregex%5D=false&_=1683154006765 HTTP/1.1" 500 110334

我认为搜索出了问题,但我不确定这里要改变什么。我认为发送到服务器的请求格式不正确,因此出现了TypeError。

mqkwyuun

mqkwyuun1#

您的Django应用程序正在尝试处理从DataTable发送的GET请求。
(You还没有向我们展示您的DataTables代码-但它看起来好像使用serverSide: true作为其选项之一。)
您可以在错误消息中看到请求(在您的问题中):
GET /API/sites/?format=datatables&draw=1&columns%5B0%5D%5Bdata%5D=0&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D = true&columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=1&columns%5B1%5D%5Bname%5D=&columns%5B1%5D% 5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=true&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=2&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D = true&columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue% 5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=asc&start=0&length=10&search%5Bvalue%5D=&search%5Bregex%5D=false&_=1683010883030 HTTP/1.1”500 136681
所以,这是一个GET -它失败了,并显示500内部服务器错误。
该请求有一个很大的查询参数字符串-该URL中/api/sites/?后面的所有内容。根据 AJAX 请求,查询参数字符串是URL编码的。
如果我们对它进行URL解码,我们会得到以下内容:
(我添加了新行以使其可读,并删除了分隔每个key=value对的每个&):

format=datatables
draw=1
columns[0][data]=0
columns[0][name]=
columns[0][searchable]=true
columns[0][orderable]=true
columns[0][search][value]=
columns[0][search][regex]=false
columns[1][data]=1
columns[1][name]=
columns[1][searchable]=true
columns[1][orderable]=true
columns[1][search][value]=
columns[1][search][regex]=false
columns[2][data]=2
columns[2][name]=
columns[2][searchable]=true
columns[2][orderable]=true
columns[2][search][value]=
columns[2][search][regex]=false
order[0][column]=0
order[0][dir]=asc
start=0
length=10
search[value]=
search[regex]=false
_=1683010883030

此请求由DataTables自动生成,并在以下情况下发送到服务器:(a)首次初始化DataTable,然后(b)每当用户执行筛选、搜索或页面导航操作时再次初始化。
您的应用需要处理此查询参数字符串,并使用其中的信息构建正确的数据集,以在其响应中发送回DataTable。该数据将包含DataTable的一页数据。
更仔细地查看请求,我们看到它包括:

start=0
length=10
order[0][column]=0
order[0][dir]=asc

这意味着从第0行(第一行)开始,并提供10行数据(第一页结果)。
它还告诉您如何构建结果的“第一页”,告诉您整个数据集需要按第0列(第一列)升序排序。
您的应用未阅读任何此信息。相反,它假设请求参数的结构完全不同。
您可以在官方的documentation中看到所有这些描述。参见“发送paraneters”。
还要注意的是,从Django发送回DataTables的响应必须与该链接中描述的预期JSON结构相匹配。参见“返回的数据”。
关于错误:
无法将关键字“0”解析到字段中。选项包括:site_description、site_id、site_name
我不确定应用程序试图读取的是哪个查询字符串零,但这就是错误的来源。
您还可以看到请求参数不包含site_descriptionsite_idsite_name的任何字段。
DataTables提供了一个通用结构,其中使用索引引用列:columns[0]columns[1]等。
如果需要,可以在DataTable定义中使用DataTables name选项。然后,请求将显示如下内容:

columns[0][name]=site_id

而不是你现在看到的这个

columns[0][name]=

然后,您可以使用这些新信息来使处理请求变得更容易。

相关问题