Django Rest Framework: AttributeError: 'NoneType' object has no attribute '_meta' [for OneToOneField]
Django Rest Framework: AttributeError: 'NoneType' object has no attribute '_meta' [for OneToOneField]
我需要有关使用 Django rest 框架的 POST 请求的帮助。
我有一个继承自 AbstractBaseUser
的 User
模型,它有 2 个字段:name
和 email
。
然后我有一个 DojoMaster
模型,它与 User
模型具有 OneToOne 关系:
class DojoMaster(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
phone = models.BigIntegerField()
country = models.ForeignKey(Country, on_delete=models.CASCADE)
我想通过 API 注册 dojo master,所以我创建了以下序列化程序:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('name', 'email', 'password')
class DojoMasterCreateSerializer(serializers.ModelSerializer):
user = UserSerializer(required=True)
class Meta:
model = DojoMaster
fields = ('user', 'phone', 'country')
def create(self, validated_data):
validated_data['country'] = Country.objects.get(
country=validated_data['country'])
user_data = validated_data.pop('user')
user = UserSerializer.create(UserSerializer(), validated_data=user_data)
subscriber, created = DojoMaster.objects.update_or_create(user=user,
phone = validated_data.pop('phone'),
country = validated_data['country'])
return subscriber
为了调用这些序列化程序,我创建了以下视图:
class DojoMasterCreateView(generics.CreateAPIView):
def post(self, request, format='json'):
serializer = DojoMasterCreateSerializer(data=request.data)
if serializer.is_valid(raise_exception=ValueError):
serializer.create(validated_data=request.data)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
对于 POST 请求的正文,我有以下内容:
{
"user": {
"name": "XYZ",
"email": "xyz@mail.com",
"password": "8Xa,9Lv&"
},
"phone": 9696510,
"country": "USA"
}
但是,当我这样做时,出现以下错误:
Traceback (most recent call last):
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
response = get_response(request)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\django\views\decorators\csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\views.py", line 494, in dispatch
response = self.handle_exception(exc)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\views.py", line 454, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\views.py", line 491, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\app_dev\development\GOQ\dojomaster_api\views.py", line 29, in post
if serializer.is_valid(raise_exception=ValueError):
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\serializers.py", line 236, in is_valid
self._validated_data = self.run_validation(self.initial_data)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\serializers.py", line 435, in run_validation
value = self.to_internal_value(data)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\serializers.py", line 465, in to_internal_value
validated_value = field.run_validation(primitive_value)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\serializers.py", line 437, in run_validation
self.run_validators(value)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\fields.py", line 533, in run_validators
for validator in self.validators:
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\fields.py", line 392, in validators
self._validators = self.get_validators()
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\serializers.py", line 1460, in get_validators
self.get_unique_for_date_validators()
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\serializers.py", line 1502, in get_unique_for_date_validators
info = model_meta.get_field_info(self.Meta.model)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\utils\model_meta.py", line 39, in get_field_info
forward_relations = _get_forward_relationships(opts)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\utils\model_meta.py", line 96, in _get_forward_relationships
not field.remote_field.through._meta.auto_created
AttributeError: 'NoneType' object has no attribute '_meta'
我不知道问题出在哪里。将不胜感激。
serializer.is_valid 方法接受关键字参数 raise_exception。它的值应该是真或假。默认情况下它是假的。如果为真,异常将被自动触发。
将 serializer.is_valid(raise_exception=ValueError)
更改为 serializer.is_valid()
。
而且为了保存序列化程序,你应该调用 save
方法而不是 create
方法
class DojoMasterCreateView(generics.CreateAPIView):
def post(self, request, format='json'):
serializer = DojoMasterCreateSerializer(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)
或简单形式
class DojoMasterCreateView(generics.CreateAPIView):
def post(self, request, format='json'):
serializer = DojoMasterCreateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
而且我不知道 user = UserSerializer.create(UserSerializer(), validated_data=user_data)
是什么意思或 create
方法逻辑在做什么。如果要保存用户数据,请按照 beloe
给出的代码进行操作
class DojoMasterCreateSerializer(serializers.ModelSerializer):
user = UserSerializer(required=True)
class Meta:
model = DojoMaster
fields = ('user', 'phone', 'country')
def create(self, validated_data):
user_data = validated_data.pop('user')
user = User.objects.create(**user_data)
subscriber, created = DojoMaster.objects.update_or_create(user=user, **validated_data)
return subscriber
并且json应该包含国家的id,比如
{
"user": {
"name": "XYZ",
"email": "xyz@mail.com",
"password": "8Xa,9Lv&"
},
"phone": 9696510,
"country": 1
}
我需要有关使用 Django rest 框架的 POST 请求的帮助。
我有一个继承自 AbstractBaseUser
的 User
模型,它有 2 个字段:name
和 email
。
然后我有一个 DojoMaster
模型,它与 User
模型具有 OneToOne 关系:
class DojoMaster(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
phone = models.BigIntegerField()
country = models.ForeignKey(Country, on_delete=models.CASCADE)
我想通过 API 注册 dojo master,所以我创建了以下序列化程序:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('name', 'email', 'password')
class DojoMasterCreateSerializer(serializers.ModelSerializer):
user = UserSerializer(required=True)
class Meta:
model = DojoMaster
fields = ('user', 'phone', 'country')
def create(self, validated_data):
validated_data['country'] = Country.objects.get(
country=validated_data['country'])
user_data = validated_data.pop('user')
user = UserSerializer.create(UserSerializer(), validated_data=user_data)
subscriber, created = DojoMaster.objects.update_or_create(user=user,
phone = validated_data.pop('phone'),
country = validated_data['country'])
return subscriber
为了调用这些序列化程序,我创建了以下视图:
class DojoMasterCreateView(generics.CreateAPIView):
def post(self, request, format='json'):
serializer = DojoMasterCreateSerializer(data=request.data)
if serializer.is_valid(raise_exception=ValueError):
serializer.create(validated_data=request.data)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
对于 POST 请求的正文,我有以下内容:
{
"user": {
"name": "XYZ",
"email": "xyz@mail.com",
"password": "8Xa,9Lv&"
},
"phone": 9696510,
"country": "USA"
}
但是,当我这样做时,出现以下错误:
Traceback (most recent call last):
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
response = get_response(request)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\django\views\decorators\csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\views.py", line 494, in dispatch
response = self.handle_exception(exc)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\views.py", line 454, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\views.py", line 491, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\app_dev\development\GOQ\dojomaster_api\views.py", line 29, in post
if serializer.is_valid(raise_exception=ValueError):
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\serializers.py", line 236, in is_valid
self._validated_data = self.run_validation(self.initial_data)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\serializers.py", line 435, in run_validation
value = self.to_internal_value(data)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\serializers.py", line 465, in to_internal_value
validated_value = field.run_validation(primitive_value)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\serializers.py", line 437, in run_validation
self.run_validators(value)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\fields.py", line 533, in run_validators
for validator in self.validators:
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\fields.py", line 392, in validators
self._validators = self.get_validators()
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\serializers.py", line 1460, in get_validators
self.get_unique_for_date_validators()
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\serializers.py", line 1502, in get_unique_for_date_validators
info = model_meta.get_field_info(self.Meta.model)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\utils\model_meta.py", line 39, in get_field_info
forward_relations = _get_forward_relationships(opts)
File "C:\Users\app_dev\Envs\game_of_quarks\lib\site-packages\rest_framework\utils\model_meta.py", line 96, in _get_forward_relationships
not field.remote_field.through._meta.auto_created
AttributeError: 'NoneType' object has no attribute '_meta'
我不知道问题出在哪里。将不胜感激。
serializer.is_valid 方法接受关键字参数 raise_exception。它的值应该是真或假。默认情况下它是假的。如果为真,异常将被自动触发。
将 serializer.is_valid(raise_exception=ValueError)
更改为 serializer.is_valid()
。
而且为了保存序列化程序,你应该调用 save
方法而不是 create
方法
class DojoMasterCreateView(generics.CreateAPIView):
def post(self, request, format='json'):
serializer = DojoMasterCreateSerializer(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)
或简单形式
class DojoMasterCreateView(generics.CreateAPIView):
def post(self, request, format='json'):
serializer = DojoMasterCreateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
而且我不知道 user = UserSerializer.create(UserSerializer(), validated_data=user_data)
是什么意思或 create
方法逻辑在做什么。如果要保存用户数据,请按照 beloe
class DojoMasterCreateSerializer(serializers.ModelSerializer):
user = UserSerializer(required=True)
class Meta:
model = DojoMaster
fields = ('user', 'phone', 'country')
def create(self, validated_data):
user_data = validated_data.pop('user')
user = User.objects.create(**user_data)
subscriber, created = DojoMaster.objects.update_or_create(user=user, **validated_data)
return subscriber
并且json应该包含国家的id,比如
{
"user": {
"name": "XYZ",
"email": "xyz@mail.com",
"password": "8Xa,9Lv&"
},
"phone": 9696510,
"country": 1
}