我有一个 Django (python) 项目。问题在于尝试对我的视图集使用创建函数,但无法识别过去的数据。 (它声称未满足 NullConstraint。)
我的views.py 包括(注意 print() 语句):
class MyModelInstModelViewSet(ABC, MyModelrModelViewSet):
dfn_class = None
def _create(self, request, *args, **kwargs):
print(request.data)
# Check if 'dfn_id' is provided in request.data
dfn_id = request.data.get('dfn_id')
if dfn_id is None:
return Response({'error': 'dfn_id is required'}, status=status.HTTP_400_BAD_REQUEST)
# Retrieve the Def instance
try:
dfn = self.dfn_class.objects.get(id=dfn_id)
except self.dfn_class.DoesNotExist:
return Response({'error': 'Invalid dfn_id'}, status=status.HTTP_400_BAD_REQUEST)
# Get default values from Def instance
data = {}
# Dynamically copy each/all fields from the Def instance
for field in dfn._meta.fields:
data[field.name] = getattr(dfn, field.name)
# Update default values with request data
for key, value in request.data.items():
# If the value is a dict/JSONField, perform a deep copy
if isinstance(value, dict):
data[key] = copy.deepcopy(value)
else:
data[key] = value
del data['id']
del data['updated_at']
data['created_at'] = timezone.now()
if data['dfn_id'] is None:
raise 'DFN ID IS NONE!'
print(data)
# Create a serializer instance with the updated data
serializer = self.serializer_class(data=data)
print('about to validate')
serializer.is_valid(raise_exception=True)
print('after validate')
# Perform creation
self.perform_create(serializer)
print('after perform_create')
return serializer
def create(self, request, *args, **kwargs):
res = self._create(request, *args, **kwargs)
if isinstance(res, Response):
return res
return Response(res.data, status=status.HTTP_201_CREATED)
class MyModelModelViewSet(MyModelInstViewSet):
...
我的 models.py 包含(注意 mymodel 模型类将 dfn 定义为 null=False):
# models.py
from enum import Enum
from django.db import models
from django.conf import settings
from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _
from secure.models import User as mymodelrUser
CHARFIELD_MAX_LENGTH = settings.CHARFIELD_MAX_LENGTH
# Create your models here.
class AbstractModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True, null=False, blank=False,)
updated_at = models.DateTimeField(auto_now_add=False, null=True, blank=False,)
barcode = models.CharField(max_length=CHARFIELD_MAX_LENGTH, null=False, blank=False,)
def clean_fields(self, fields):
if fields is None:
fields = self._meta.fields
for field in fields:
# Generate method name for field
method_name = f"clean_{field.name}"
# Check if method exists and call it
if hasattr(self, method_name):
getattr(self, method_name)()
def save(self, *args, **kwargs):
self.clean_fields(None)
super().save(*args, **kwargs)
def __str__(self):
if self.pk: # Check if the object has been saved to the database
id = self.pk
else:
id = '<None>'
if self.barcode:
barcode = f"\"{self.barcode}\""
else:
barcode = '<None>'
return f"[{self.__module__}.{self.__class__.__name__}(id={id}, code={barcode})]"
class Meta:
abstract = True
ordering = ['updated_at', 'created_at',]
# Base Model class for all Def models
class AbstractDefModel(AbstractModel):
class Meta:
abstract = True
# Base Model class for all instance models
class AbstractInstModel(AbstractModel):
class Meta:
abstract = True
# mymodel Models
class mymodelFields(models.Model):
...
class Meta:
abstract = True
class mymodelDef(AbstractDefModel, mymodelFields):
parent = models.ForeignKey('self', on_delete=models.CASCADE, related_name='children', null=True, blank=False,)
class Meta(AbstractDefModel.Meta):
abstract = False
constraints = [
models.UniqueConstraint(fields=['barcode'], name='constraint_unique_mymodelrdef_barcode')
]
verbose_name = 'mymodeldef'
verbose_name_plural = 'mymodeldefs'
class mymodel(AbstractInstModel, mymodelFields):
parent = models.ForeignKey('self', on_delete=models.CASCADE, related_name='children', null=True, blank=False,)
dfn = models.ForeignKey('mymodelDef', on_delete=models.CASCADE, related_name='instances', null=False, blank=False,)
address = models.CharField(max_length=CHARFIELD_MAX_LENGTH, null=False, blank=False,)
class Meta(AbstractInstModel.Meta):
abstract = False
verbose_name = 'mymodel'
verbose_name_plural = 'mymodels'
我的网址.py:
# urls.py
from django.urls import path, include
from . import views
from rest_framework import routers
router = routers.DefaultRouter()
router.register(prefix=r'mymodels', viewset=views.MyModelViewSet, basename='mymodel')
urlpatterns = [
path('api/', include(router.urls)),
path('', views.home_view, name='home'),
]
当我使用有效负载发布 /api/mymodel/ 时:
{
"dfn_id": 11,
"barcode": "Test DFNID POST CREATE!",
"address": "This is a test"
}
我的运行服务器抛出此错误:
(venv) D:\projects\mymodeler>python manage.py runserver
Watching for file changes with StatReloader
[2024-03-03 21:00:09] [INFO]: Watching for file changes with StatReloader
[Path]: D:\projects\mymodeler\venv\lib\site-packages\django\utils\autoreload.py:668
Performing system checks...
System check identified no issues (0 silenced).
March 03, 2024 - 21:00:10
Django version 5.0.1, using settings 'mymodeler.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
{'dfn_id': 11, 'barcode': 'Test DFNID POST CREATE!', 'address': 'This is a test'}
{'external_id': None, 'created_at': datetime.datetime(2024, 3, 3, 10, 0, 12, 33136, tzinfo=datetime.timezone.utc), 'options': None, 'status': 1, 'barcode': 'Test DFNID POST CREATE!', 'is_virtual': False, 'is_storage': False, 'is_mobile': False, 'max_weight': None, 'max_height': None, 'max_width': None, 'max_length': None, 'parent': None, 'dfn_id': 11, 'address': 'This is a test'}
about to validate
after validate
Internal Server Error: /api/mymodels/
Traceback (most recent call last):
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\backends\utils.py", line 105, in _execute
return self.cursor.execute(sql, params)
psycopg2.errors.NotNullViolation: null value in column "dfn_id" of relation "core_mymodel" violates not-null constraint
DETAIL: Failing row contains (63, null, null, 2024-03-03 10:00:12.035136+00, null, Test DFNID POST CREATE!, f, 1, f, f, null, null, null, null, This is a test, null, null, null, null, null, null).
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "D:\projects\mymodeler\venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "D:\projects\mymodeler\venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "D:\projects\mymodeler\venv\lib\site-packages\django\views\decorators\csrf.py", line 65, in _view_wrapper
return view_func(request, *args, **kwargs)
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
return self.dispatch(request, *args, **kwargs)
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "D:\projects\mymodeler\core\views.py", line 170, in create
res = self._create(request, *args, **kwargs)
File "D:\projects\mymodeler\core\views.py", line 164, in _create
self.perform_create(serializer)
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\mixins.py", line 24, in perform_create
serializer.save()
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\serializers.py", line 212, in save
self.instance = self.create(validated_data)
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\serializers.py", line 962, in create
instance = ModelClass._default_manager.create(**validated_data)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\manager.py", line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\query.py", line 677, in create
obj.save(force_insert=True, using=self.db)
File "D:\projects\mymodeler\core\models.py", line 39, in save
super().save(*args, **kwargs)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\base.py", line 822, in save
self.save_base(
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\base.py", line 909, in save_base
updated = self._save_table(
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\base.py", line 1067, in _save_table
results = self._do_insert(
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\base.py", line 1108, in _do_insert
return manager._insert(
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\manager.py", line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\query.py", line 1845, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\sql\compiler.py", line 1823, in execute_sql
cursor.execute(sql, params)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\backends\utils.py", line 122, in execute
return super().execute(sql, params)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\backends\utils.py", line 79, in execute
return self._execute_with_wrappers(
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\backends\utils.py", line 92, in _execute_with_wrappers
return executor(sql, params, many, context)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\backends\utils.py", line 100, in _execute
with self.db.wrap_database_errors:
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\utils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\backends\utils.py", line 105, in _execute
return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: null value in column "dfn_id" of relation "core_mymodel" violates not-null constraint
DETAIL: Failing row contains (63, null, null, 2024-03-03 10:00:12.035136+00, null, Test DFNID POST CREATE!, f, 1, f, f, null, null, null, null, This is a test, null, null, null, null, null, null).
[2024-03-03 21:00:12] [ERROR]: Internal Server Error: /api/mymodels/
[Path]: D:\projects\mymodeler\venv\lib\site-packages\django\utils\log.py:241
Traceback (most recent call last):
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\backends\utils.py", line 105, in _execute
return self.cursor.execute(sql, params)
psycopg2.errors.NotNullViolation: null value in column "dfn_id" of relation "core_mymodel" violates not-null constraint
DETAIL: Failing row contains (63, null, null, 2024-03-03 10:00:12.035136+00, null, Test DFNID POST CREATE!, f, 1, f, f, null, null, null, null, This is a test, null, null, null, null, null, null).
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "D:\projects\mymodeler\venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "D:\projects\mymodeler\venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "D:\projects\mymodeler\venv\lib\site-packages\django\views\decorators\csrf.py", line 65, in _view_wrapper
return view_func(request, *args, **kwargs)
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
return self.dispatch(request, *args, **kwargs)
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "D:\projects\mymodeler\core\views.py", line 170, in create
res = self._create(request, *args, **kwargs)
File "D:\projects\mymodeler\core\views.py", line 164, in _create
self.perform_create(serializer)
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\mixins.py", line 24, in perform_create
serializer.save()
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\serializers.py", line 212, in save
self.instance = self.create(validated_data)
File "D:\projects\mymodeler\venv\lib\site-packages\rest_framework\serializers.py", line 962, in create
instance = ModelClass._default_manager.create(**validated_data)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\manager.py", line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\query.py", line 677, in create
obj.save(force_insert=True, using=self.db)
File "D:\projects\mymodeler\core\models.py", line 39, in save
super().save(*args, **kwargs)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\base.py", line 822, in save
self.save_base(
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\base.py", line 909, in save_base
updated = self._save_table(
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\base.py", line 1067, in _save_table
results = self._do_insert(
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\base.py", line 1108, in _do_insert
return manager._insert(
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\manager.py", line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\query.py", line 1845, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\models\sql\compiler.py", line 1823, in execute_sql
cursor.execute(sql, params)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\backends\utils.py", line 122, in execute
return super().execute(sql, params)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\backends\utils.py", line 79, in execute
return self._execute_with_wrappers(
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\backends\utils.py", line 92, in _execute_with_wrappers
return executor(sql, params, many, context)
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\backends\utils.py", line 100, in _execute
with self.db.wrap_database_errors:
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\utils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "D:\projects\mymodeler\venv\lib\site-packages\django\db\backends\utils.py", line 105, in _execute
return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: null value in column "dfn_id" of relation "core_mymodel" violates not-null constraint
DETAIL: Failing row contains (63, null, null, 2024-03-03 10:00:12.035136+00, null, Test DFNID POST CREATE!, f, 1, f, f, null, null, null, null, This is a test, null, null, null, null, null, null).
[03/Mar/2024 21:00:12] "POST /api/mymodels/ HTTP/1.1" 500 218095
打印语句正在打印,并清楚地表明传递给序列化器构造函数的数据字典具有“dfn_id”键(在本例中值为 11)。那么我如何让 'dfn_id' 为 None 呢?
提前非常感谢您的任何见解。
我不是专家,但也许提供
dfn
而不是 dfn_id
就能完成工作。
如果您提供序列化器,它将有更多帮助。