Reputation: 2316
Tried to write custom create
method for my model, but run into some unclear errors.
Here is my code:
# models.py:
class ItemModel(models.Model):
item_id = models.CharField(max_length=10, primary_key=True)
name = models.CharField(max_length=40)
active = models.BooleanField(default=True)
def __str__(self):
return self.item_id
class ItemVersion(models.Model):
item_ver_id = models.CharField(max_length=13, primary_key=True)
item_ver = models.TextField()
config = models.TextField()
model = models.ForeignKey(ItemModel, on_delete=models.CASCADE, default=0)
session_id = models.CharField(max_length=40, default=0)
creation_date = models.DateTimeField(auto_now=False, auto_now_add=True)
finished = models.BooleanField(default=False)
def name(self):
return self.model.name
def __str__(self):
return str(self.model)
# serializers.py:
class ItemModelSerializer(serializers.ModelSerializer):
item_id = serializers.RegexField(regex='^\d{3}-\d{9}$', allow_blank=False)
name = serializers.CharField(min_length=6, max_length=50, allow_blank=False)
class Meta:
model = ItemModel
fields = '__all__'
class ItemVersionSerializer(serializers.ModelSerializer):
item_ver_id = serializers.RegexField(regex='^r\d{2}$', allow_blank=False)
session_id = serializers.RegexField(regex='^s\d{2}$', allow_blank=False)
link = serializers.SerializerMethodField()
name = serializers.SerializerMethodField()
config = serializers.CharField(min_length=6)
item_ver = serializers.CharField(min_length=6)
def get_name(self, obj):
return obj.name()
def get_link(self, obj):
link = 'https://example.net/' + str(obj.model)
+ str('-dyn') + '/?iv_id=' + str(obj.item_ver_id)
+ '&sessid=' + str(obj.session_id)
return link
# views.py:
class ItemModelViewSet(viewsets.ModelViewSet):
queryset = ItemModel.objects.all()
serializer_class = ItemModelSerializer
lookup_field = 'item_id'
class ItemVersionViewSet(viewsets.ModelViewSet):
serializer_class = ItemVersionSerializer
lookup_field = 'item_ver_id'
def get_queryset(self):
pass
def create(self, request, *args, **kwargs):
data = request.data
model = ItemModel.objects.get(item_id=data["model"])
item_version = ItemVersion.objects.create(
# model=model,
item_ver_id=data["item_ver_id"],
config=data["config"],
item_ver=data["item_ver"],
session_id=data["session_id"]
# finished=data["finished"]
)
item_version.model.add(model)
finished = True if data["finished"] else False
item_version.finished.add(finished)
item_version.save()
serializer = ItemVersionSerializer(item_version)
return Response(data)
For some reason, I keep getting FOREIGN KEY constraint failed
and the session_id=data["session_id"]
line is highlighted as the one where problem occurs nearby.
Any ideas how to solve this?
Edit: traceback:
Traceback (most recent call last):
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 383, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: FOREIGN KEY constraint failed
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/rest_framework/viewsets.py", line 116, in view
return self.dispatch(request, *args, **kwargs)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/rest_framework/views.py", line 495, in dispatch
response = self.handle_exception(exc)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/rest_framework/views.py", line 455, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/rest_framework/views.py", line 492, in dispatch
response = handler(request, *args, **kwargs)
File "/home/aqv/workspace/django_rest_fw/ct_test/core/views.py", line 47, in create
session_id=data["session_id"]
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/models/query.py", line 422, in create
obj.save(force_insert=True, using=self.db)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/models/base.py", line 741, in save
force_update=force_update, update_fields=update_fields)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/models/base.py", line 779, in save_base
force_update, using, update_fields,
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/models/base.py", line 870, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/models/base.py", line 908, in _do_insert
using=using, raw=raw)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/models/query.py", line 1186, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1332, in execute_sql
cursor.execute(sql, params)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/backends/utils.py", line 99, in execute
return super().execute(sql, params)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/backends/utils.py", line 67, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/backends/utils.py", line 76, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/aqv/workspace/django_rest_fw/ct_test/environ/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 383, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: FOREIGN KEY constraint failed
Upvotes: 0
Views: 43
Reputation: 8674
The only foreign key I see is model
there, and in your code you aren't passing it.
def create():
model = ItemModel.objects.get(item_id=data["model"])
item_version = ItemVersion.objects.create(
# model=model,
...
This will cause the FK constraint issue if you do not pass in a valid model instance or id because:
default=0
for the model field ItemModel
with pk=0 exists in the databsaeIf you want model
to be nullable, then you can just add that to the FK definition:
class ItemVersion(models.Model):
...
model = models.ForeignKey(ItemModel, null=True, on_delete=CASCADE)
Later on I see you have these 2 lines:
item_version.model.add()
item_version.finished.add(finished)
. These are both incorrect. add()
doesn't work on boolean model field, and the .add()
for an FK is only valid for many-to-many FKs, which are not being used here. The way you are passing them in the commented out sections is fine.
You can get a default value for the 'finished' flag by saying:
data.get('finished', False)
# this will throw a KeyError if "finished" isn't in the dict
True if data["finished"] else False
# this will not throw an error (but doesn't check the value of finished)
True if "finished" in data else False
Some other notes:
1) You use a ModelSerializer without a Meta class inside. Consider just using a standard serializer if you really want to do it by hand, or read up on ModelSerializers. If you use it correctly you shouldn't need a custom create method in the viewset.
2) default=<anything>
is not a good idea on an FK. An FK should not generally have a default value (though there are some cases where its nice, like with pre-defined system data in constant tables)
3) You aren't using a serializer in your create
method. You are accessing request.data directly. This will give you no validation, and no ability to say finished=BooleanField(default=False)
and always get a value for serializer.validated_data['finished']
.
Upvotes: 2