Django的REST框架:渲染列表响应表单元素(Django REST Framework: re

2019-10-29 18:31发布

如何Django的REST框架可以用来渲染模型实例与由用户编辑的特定字段列表?

我是几个月到Django的,只有一两天到DRF。 我尝试过几种不同的方法,但似乎无法环绕它我的头。

在此之前使用DRF,我的工作流程将是建立一个视图(以及相关的URL)认为:查询我的模型,从forms.py(只露出我所需要的字段)拿了我的自定义表单,把二者连成一本字典,并把它交给一个模板。

在模板,然后我可以依次通过我的模型实例,并建立了我的编辑字段,通过Django的酥脆形式管路他们,因为需要。

然后,我可以通过一个AJAX get请求调用这个模板。

models.py

class Buyer(models.Model):
  name = models.CharField(unique=True, max_length = 20)

class Item(models.Model):
  name = models.CharField(unique=True, max_length = 50)
  active = models.BooleanField(default=True)
  bought_by = models.ForeignKey(Buyer, null=True, blank=True, to_field="name",)

views.py

class ItemViewSet(viewsets.ModelViewSet):
  queryset = models.Item.objects.select_related("bought_by")
  serializer_class= serializers.ItemSerializer
  filterset_fields = ("bought_by")

serializers.py

class ItemSerializer(serializers.HyperlinkedModelSerializer):
  class Meta:
    model = models.Item
    fields = "__all__"
    extra_kwargs = {"url": {"view_name: "myapp:item-detail"}}

urls.py

router = routers.DefaultRouter()
router.register(r"items", views.ItemViewSet)

template.html

{% load static %}
{% load rest_framework %}

<table id="item_table" class="table">
  <thead>
    <tr>
      <th scope="col">Name</th>
      <th scope="col">Active</th>
      <th scope="col">Buyer</th>
    </tr>
  </thead>

  <tbody>
    {% for item in data %}
      <tr scope="row">
        <td>{{ item.name }}</td>
        <td>{{ item.active }}</td>
        <td>{{ item.bought_by }}</td>
      </tr>
    {% endfor %}
  </tbody>
</table>

一些JS文件

function getData(){
  updateRequest = $.ajax({
    type: "GET",
    url: "myapp/items/",
    success: function(data) {
      //....
    }
  });
}

第一种方法:自定义ListModelMixin为ItemViewSet呈现模板,并沿着串行传递。 沿着线的东西:

def list(self,request, *args, **kwargs):
  ...
  return Response ({'data': queryset, 'serializer': serializer}, template_name = "myapp/template.html")

然后在template.html变化{{item.active}}到:

<form action="{{ item.url }}" method="post">
  {% csrf_token %}
  {{ render_form serializer }}
</form>

错误:串行不迭代。 说得通。 将其改为:

{{ render_field item.bought_by }}

错误:需要“风格”,补充说。 继续获得其他错误

第二条本办法:试着修改ListModelMixin收集序列化模型实例的字典例如,:

items= dict()
        for item in queryset:
            items[item] = serializers.ItemSerializer(item, data=request.data)

从来没有完全想通了这一点作为serializers.ItemSerializer(项数据= request.data)似乎没有成为一个字典项目,因此无法使用data.items()通过它在模板中进行迭代。

对于长写的道歉,但我有点在海上,而不是很清楚如何进行。

什么是某些字段可编辑(类似于你将如何在与list_editable指定Django管理)返回所有模型实例的列表的最优雅的方式DRF?

我总是老的方式,但感觉就像我失去了一些东西明显与DRF这里。

参考文献:

https://www.django-rest-framework.org/topics/html-and-forms/

Django的REST框架串行单独呈现形式

渲染与APIView的Django的REST框架的ModelViewSet类INSEAD形式

Answer 1:

解决了

方法有两个最接近:有条件地选择一个渲染器和覆盖默认.LIST()。

views.py:

from rest_framework import renderers
from rest_framework.response import Response

class ItemViewSet(viewsets.ModelViewSet):
  queryset = models.Item.objects.select_related("bought_by")
  serializer_class= serializers.ItemSerializer
  filterset_fields = ("bought_by")
  renderer_classes = [renderers.JSONRenderer, renderers.BrowsableAPIRenderer, renderers.TemplateHTMLRenderer]

  def list(self, request, *args, **kwargs):
    queryset = self.filter_queryset(self.get_queryset())

    if request.accepted_renderer.format == "html":
      items = list()

      for item in queryset:
        items.append({"serializer": self.get_serializer(ticket), "item": item})

      return Response(
        {
          "items_info": items,
          "style": {"template_pack": "rest_framework/inline/"},
        },
        template_name="myapp/items_list.html",
      )
    else:
     page = self.paginate_queryset(queryset)
     if page is not None:
       serializer = self.get_serializer(page, many=True)
       return self.get_paginated_response(serializer.data)

      serializer = self.get_serializer(queryset, many=True)

    return Response(serializer.data)

这将检查请求的URL有一个/?格式= HTML 后缀 。 如果是的话它会序列在查询集的每个项目,包括列表,发送给items_list.html词典(上下文){串行项目}字典。

为了render_field,DRF需要一个风格定义。

如果格式后缀不是HTML,或没有指定,它会优先考虑JSON渲染器或BrowsableAPI渲染器(在默认渲染器 )。 通过这种方式,我们可浏览API和JSON API仍然轻松地工作。

为了与bought_by场编辑为每个实例呈现此,沿着这些线路修改你的模板(在这种情况下items_list.html):

{% load static %}
{% load rest_framework %}

{% if items_info %}
  {% csrf_token %}

  <table id="Items_Table" class="table">
    <thead>
      <tr>
       <th scope="col">Name</th>
       <th scope="col">Active</th>
       <th scope="col">Bought By</th>
      </tr>
    </thead>

    <tbody>
      {% for pair in items_info %}

        <tr scope="row">
          <td>{{ pair.item.name }}</td>
          <td>{{  pair.item.active  }}</td>
          <td>
            <form action="{% url "myapp:item-detail" pair.item.pk %}" method="PATCH">
            {% render_field pair.serializer.bought_by style=style %}
            </form>
          </td>
        </tr>

      {% endfor %}
    </tbody>
  </table>

{% else %}
  <p class="text-center">No items to show.</p>
{% endif %}

现在,在您的GET请求追加只是“/?格式= HTML”的网址。

如果你正在使用AJAX,发送POST / PUT / PATCH /等时。 请求, 包括如Django文档中所描述的CSRF令牌 。



文章来源: Django REST Framework: rendering form elements in list response