【问题标题】:Getting a POST request to act like a GET request? djangorestframework-datatables让 POST 请求像 GET 请求一样工作? djangorestframework-datatables
【发布时间】:2020-08-28 22:58:51
【问题描述】:

我不想将数据添加到数据库中,就像 djangorestframework-datatables 尝试对 POST 请求执行的操作一样。我需要使用 POST 请求而不是 GET 请求,因为 GET 请求的 URI 太长(我不得不将生产服务器上的 nginx 和 gunicorn 限制更改为无限长度(最大值不够)​​,这会打开站点最多ddos攻击,这显然不太理想。

代码如下:

# api/serializers

class ReportSerializer(serializers.ModelSerializer):
    class Meta:
        model = Report
        fields = "__all__"

# api/views

class ReportViewSet(viewsets.ModelViewSet):
    queryset = Report.objects.all()
    serializer_class = ReportSerializer

# reports/models

class Report(models.Model):

    contribution_expenditure_type = models.CharField(max_length=255, choices=CONTRIBUTION_EXPENDITURE_TYPES)

    filer_id = models.BigIntegerField()
    filer_namL = models.CharField(max_length=255)
    report_num = models.CharField(max_length=255)
    committee_type = models.CharField(max_length=255)
    rpt_date = models.CharField(max_length=255)
    from_date = models.CharField(max_length=255)
    thru_date = models.CharField(max_length=255)
    elect_date = models.CharField(max_length=255)
    rec_type = models.CharField(max_length=255)
    form_type = models.CharField(max_length=255, blank=True, null=True)
    tran_id = models.CharField(max_length=255, blank=True, null=True)
    entity_cd = models.CharField(max_length=255, blank=True, null=True)
    tran_namL = models.CharField(max_length=255)
    tran_namF = models.CharField(max_length=255, blank=True, null=True)
    tran_city = models.CharField(max_length=255, blank=True, null=True)
    tran_state = models.CharField(max_length=255, blank=True, null=True)
    tran_zip4 = models.CharField(max_length=255, blank=True, null=True)
    tran_emp = models.CharField(max_length=255, blank=True, null=True)
    tran_occ = models.CharField(max_length=255, blank=True, null=True)
    tran_self = models.CharField(max_length=255, blank=True, null=True)
    tran_type = models.CharField(max_length=255, blank=True, null=True)
    tran_date = models.CharField(max_length=255)
    tran_date1 = models.CharField(max_length=255, blank=True, null=True)
    tran_amt1 = models.DecimalField(max_digits=10, decimal_places=2)
    tran_amt2 = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    cmte_id = models.CharField(max_length=255, blank=True, null=True)
    intr_namL = models.CharField(max_length=255, blank=True, null=True)
    intr_city = models.CharField(max_length=255, blank=True, null=True)
    intr_state = models.CharField(max_length=255, blank=True, null=True)
    intr_zip4 = models.CharField(max_length=255, blank=True, null=True)
    intr_self = models.CharField(max_length=255, blank=True, null=True)
    int_cmteId = models.CharField(max_length=255, blank=True, null=True)

    efiling_link = models.URLField(blank=True, null=True)

    date_report_added = models.DateTimeField(auto_now_add=True, blank=True, null=True)
    date_efiling_added = models.DateTimeField(blank=True, null=True)

    county = models.ForeignKey(County, on_delete=models.CASCADE, blank=True, null=True)

    def __str__(self):
        return self.filer_namL

    def get_datetime_report_date(self):
        return datetime.strptime(self.rpt_date, '%Y-%m-%d %H:%M:%S')

    class Meta:
        unique_together = ('tran_id', 'form_type')

# api/urls

from django.conf.urls import url
from django.urls import path, include
from rest_framework import routers

from .viewsets import registration_views as reg_views
from . import views

router = routers.SimpleRouter()

# Register router with Viewsets from the registration views file
router.register(r'users', reg_views.UserViewSet, basename="users")
router.register(r'reports', views.ReportViewSet, basename="reports") #/api/v1/reports/

report_list = views.ReportViewSet.as_view({
    'get': 'list',
    'post': 'retrieve'
})

urlpatterns = [
    path('store/', views.api_store, name="store"),
    path('stop_store/', views.api_store_stop, name="stop_store"),
    path('poll_store_status/', views.poll_store_status, name="poll_store_status"),
    path('scrape/', views.api_scrape, name="scrape"),
    path('stop_scrape/', views.api_scrape_stop, name="stop_scrape"),
    path('poll_scrape_status/', views.poll_scrape_status, name='poll_scrape_status'),
    path('get_items/', views.get_items, name="get_items"),
    path('get_all_items/', views.get_all_items, name="get_all_items"),
    path('get_netviz_reports/', views.get_netviz_reports, name='get_netviz_reports'),

    path('get_datatables_items/', report_list, name='report_list'),
]

# main.js

  Data.columns = [];
  $('th').each(function(item,i){
    Data.columns.push({'data': $(this).text().trim()})
  });
  $('#searchtable').DataTable({
    'serverSide': true,
    'ajax': {
      'url': '/api/get_datatables_items/?format=datatables',
      'type': 'POST',
      'columns': Data.columns,
      'beforeSend': function (request) {
        request.setRequestHeader("X-CSRFToken", Cookies.get('csrftoken'));
      }
    }
  });

我正在使用 djangorestframework、djangorestframework-datatables 和 jquery.datatables(前端)。任何帮助表示赞赏。

【问题讨论】:

    标签: python django django-rest-framework datatables


    【解决方案1】:

    https://github.com/encode/django-rest-framework/blob/master/rest_framework/mixins.py

    重写 ReportViewset 中的 create 方法

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        #self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
    

    self.perform_create(serializer) 是访问数据库的对象。

    【讨论】:

    • 所以,这使得没有保存任何内容,这是理想的,但是将通过 GET 请求加载的数据没有通过 POST 请求加载。 datatables 说加载了 22 个项目(应该是数千个),但是表是空的
    猜你喜欢
    • 1970-01-01
    • 2014-07-24
    • 2020-11-09
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2018-12-05
    相关资源
    最近更新 更多