【问题标题】:Post to django rest framework发布到 django rest 框架
【发布时间】:2017-12-25 13:55:07
【问题描述】:

我想使用 post 发布到我的 Django 服务器,这样我就可以添加一个 todo 项目。这是模型:

class Todo(models.Model):
    title = models.CharField(max_length=200);
    text = models.TextField()
    completed = models.BooleanField(default=False)
    created_at = models.DateTimeField(default=datetime.now, blank = True )
    def __str__(self):
        return self.title

还有序列化器:

class TodoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Todo
        fields = ("id", 'title','text', 'completed', 'created_at')

并查看:

class TodoList(APIView):
    def get(self,request):
        todo=Todo.objects.all()
        serializer=TodoSerializer(todo,many=True)
        return Response(serializer.data)
    def post(self,request):
        Todo.objects.create(
            title=request.POST.get('title'),
            text=request.POST.get('text'))
        return HttpResponse(status=201)

我的发帖请求是

{ "title": "new title",
  "text": "a test text"}

它告诉我

IntegrityError at /todos/
(1048, "Column 'title' cannot be null")

作为 Django 的新手,我不明白这个错误。有什么想法吗?

【问题讨论】:

  • 不要像这样创建,您可以随时使用序列化程序。

标签: python django post django-rest-framework


【解决方案1】:

您可以始终使用序列化器来代替这样的创建方式

data_serializer = TodoSerializer(data=request.data)
if data_Serializer.is_valid():
    data_Serializer.save()

【讨论】:

  • 谢谢这很好用,你能告诉我这如何与 PUT 和 DELETE 请求一起工作吗?
【解决方案2】:

您需要访问request.data 而不是request.POST

def post(self,request):
    serializer = TodoSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

【讨论】:

    【解决方案3】:

    对于放置请求:

    todo_item = Todo.objects.get(id=id) // Need to get that element
    data_serializer = TodoSerializer(instance=todo_item,data=request.data, partial=True)
    if data_Serializer.is_valid():
       data_Serializer.save()
    else:
       print  data_Serializer.errors
    

    删除:

    todo_item = Todo.objects.get(id=id) // Need to get that element
    todo_item.delete()
    

    【讨论】:

      【解决方案4】:

      由于您在 cmets 中询问了除了 post 之外的其他方法,因此我将展示一个 ModelViewSet 示例,它允许您发布以添加 Todo,并为检索、更新和删除您的待办事项。

      推荐阅读:
      http://www.django-rest-framework.org/api-guide/viewsets/#modelviewset

      from rest_framework.viewsets import ModelViewSet
      from todo.models import Todo
      from todo.serializers import TodoSerializer
      
      class TodoViewSet(ModelViewSet):
          queryset = Todo.objects.all()
          serializer_class = TodoSerializer
      

      ModelViewSet 类将为您提供视图方法的默认实现,以列出、创建、检索、更新(全部或部分更新)和删除 Todo。这些动作映射到不同url的某些方法,get映射到list和retrieve,post映射到create,put和patch映射到update和partial_update,delete映射到destroy。

      然后在您的 urls.py 中,使用 TodoViewSet.as_view(...) 包含 TodoViewSet:

      from django.conf.urls import url
      from todo.views import TodoViewSet
      
      urlpatterns = [
          url(
              r'^todos/$',
              TodoViewSet.as_view({'get': 'list', 'post': 'create'}),
              name='todo-list',
          ),
          url(
              r'^todos/(?P<pk>\d+)/$',
              TodoViewSet.as_view({'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'}),
              name='todo-detail',
          )
      ]
      

      这里我们明确说明了请求方法到我之前提到的查看操作的映射。

      【讨论】:

      • 感谢您的帮助。 urls.py 中的 (?p\d+) 匹配是什么?
      • (?P\d+) 是一个正则表达式占位符,用于捕获 url 中的 Todo 对象主键并查找对象,在这种情况下应该是一个整数。您可以自定义视图期望从 url 获得的字段以及它用于查找的模型上的哪个字段。 django-rest-framework.org/api-guide/generic-views/…
      猜你喜欢
      • 2021-12-09
      • 2015-06-18
      • 1970-01-01
      • 2014-09-21
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多