首页 > 解决方案 > 无法创建新模型并将其保存到数据库中。Django rest框架视图模型集

问题描述

我有一个 django rest 框架项目。我正在尝试构建一个覆盖 ModelViewSet 的默认创建方法的视图集。现在,我正在从 POST 请求和 url 参数中获取我需要获取的所有数据。我正在尝试将它们存储到一个数据对象中,然后基于相同的数据对象在数据库中创建一个新对象。

所有数据都是正确的并在对象中设置。我怎样才能使对象可保存。我收到一个错误,我认为它来自我尝试保存时。虽然我不确定....

模型视图集 - 创建方法:

    @permission_classes((IsAuthenticated))
    def create(self, request, *args, **kwargs):
        namespace = self.kwargs.get('namespace', None)
        path = self.kwargs.get('path', None)
        print(request.user)
        print(request.POST.get('version'))
        print(request.POST.get('namespace'))
        print(request.POST.get('path'))
        print(request.POST.get('value'))
        print(request.user.id)
        if namespace is None and path is None:
            return super().create(request)
        if namespace and path is None:
            data = {
                "person":request.user,
                'version':request.Post.get('version'),
                'namespace':namespace,
                'path':request.Post.get('path'),
                'value':request.Post.get('value'),
                'user_id':request.user.id,
            }
            return super().create(data)
        if namespace and path:
            data = {
                "person":self.request.user,
                'version':self.request.Post.get('version'),
                'namespace':namespace,
                'path':path,
                'value':self.request.Post.get('value'),
                'user_id':self.request.user.id,
            }
            return super().create(data)

模型:

from django.db import models
from django.contrib.auth.models import User
from owf_framework.people.models import Person

class Preference(models.Model):
    id = models.BigAutoField(primary_key=True, null=False)
    version = models.BigIntegerField(default=1, null=False)
    path = models.CharField(max_length=200, null=False)
    namespace = models.CharField(max_length=200, null=False)
    value = models.TextField(null=False)
    user_id = models.BigIntegerField(null=False, default=1)
    person = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.namespace

    class Meta:
        db_table = 'preference'

这是错误:

AttributeError at /api/v2/preferences/namespace1/
'Request' object has no attribute 'Post'
Request Method: POST
Request URL:    http://127.0.0.1:8000/api/v2/preferences/namespace1/
Django Version: 2.2.1
Exception Type: AttributeError
Exception Value:    
'Request' object has no attribute 'Post'
Exception Location: C:\Users\jandali\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\request.py in __getattr__, line 414
Python Executable:  C:\Users\jandali\AppData\Local\Programs\Python\Python37-32\python.exe
Python Version: 3.7.3
Python Path:    
['C:\\Users\\jandali\\desktop\\ozone-backend\\ozone-framework-python-server',
 'C:\\Users\\jandali\\AppData\\Local\\Programs\\Python\\Python37-32\\python37.zip',
 'C:\\Users\\jandali\\AppData\\Local\\Programs\\Python\\Python37-32\\DLLs',
 'C:\\Users\\jandali\\AppData\\Local\\Programs\\Python\\Python37-32\\lib',
 'C:\\Users\\jandali\\AppData\\Local\\Programs\\Python\\Python37-32',
 'C:\\Users\\jandali\\AppData\\Roaming\\Python\\Python37\\site-packages',
 'C:\\Users\\jandali\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages']
Server time:    Wed, 10 Jul 2019 04:22:02 +0000
Traceback Switch to copy-and-paste view
C:\Users\jandali\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\request.py in __getattr__
            return getattr(self._request, attr) …
▶ Local vars
During handling of the above exception ('WSGIRequest' object has no attribute 'Post'), another exception occurred:
C:\Users\jandali\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\exception.py in inner
            response = get_response(request) …
▶ Local vars
C:\Users\jandali\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py in _get_response
                response = self.process_exception_by_middleware(e, request) …
▶ Local vars
C:\Users\jandali\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py in _get_response
                response = wrapped_callback(request, *callback_args, **callback_kwargs) …
▶ Local vars
C:\Users\jandali\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\views\decorators\csrf.py in wrapped_view
        return view_func(*args, **kwargs) …
▶ Local vars
C:\Users\jandali\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\viewsets.py in view
            return self.dispatch(request, *args, **kwargs) …
▶ Local vars
C:\Users\jandali\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\views.py in dispatch
            response = self.handle_exception(exc) …
▶ Local vars
C:\Users\jandali\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\views.py in handle_exception
            self.raise_uncaught_exception(exc) …
▶ Local vars
C:\Users\jandali\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\views.py in dispatch
            response = handler(request, *args, **kwargs) …
▶ Local vars
C:\Users\jandali\desktop\ozone-backend\ozone-framework-python-server\owf_framework\preferences\views.py in create
                'version':request.Post.get('version'), …
▶ Local vars
C:\Users\jandali\AppData\Local\Programs\Python\Python37-32\lib\site-packages\rest_framework\request.py in __getattr__
            return self.__getattribute__(attr) 

标签: pythondjangodjango-rest-frameworkdjango-views

解决方案


requestobject 没有任何名为 的属性Post。它可以是request.POST,或者您也可以从request.dataDRF 中获取数据。

另外,我认为这条线有问题:

return super().create(data)

原因是,调用超类时,需要匹配其方法签名。意思是,调用超类时需要传递正确的参数和关键字参数。所以它应该是这样的:

return super().create(request, *args, **kwargs)

现在,根据create方法的实现,它不需要data你准备的任何命名参数。因为它使用request.data序列化程序中的参数来创建对象。

所以我认为你可以这样进行:

 from rest_framework import status
 from rest_framework.response import 



@permission_classes((IsAuthenticated))
def create(self, request, *args, **kwargs):
    namespace = self.kwargs.get('namespace', None)
    path = self.kwargs.get('path', None)
    if namespace is None and path is None:
        return super().create(request, *args, **kwargs)
    if namespace and path is None:
        data = {
            "person":request.user.id,
            'version':request.data.get('version'),
            'namespace':namespace,
            'path':request.data.get('path'),
            'value':request.data.get('value'),
            'user_id':request.user.id,
        }

    if namespace and path:
        data = {
            "person":request.user.id,
            'version':request.data.get('version'),
            'namespace':namespace,
            'path':path,
            'value':request.data.get('value'),
            'user_id':request.user.id,
        }
    serializer = self.get_serializer(data=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)

推荐阅读