Error during deleting
oleksandr-shvab opened this issue · comments
Hi all! I just had a strange error in my work project. It's an ML project where user can create projects, upload datasets and then work with them.
First of all, we have a Project model:
class Project(CustomModel):
name = models.CharField(max_length=30)
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
Here is nothing special, just CustomModel where we extend create and update methods to call full_clean().
The next one is the DatasetFolder model where uploaded files lay:
class DatasetFolder(CustomModel):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
...
Then go first polymorphic model. It's the parent model that describes all the uploaded files:
class OriginalFile(PolymorphicModel, CustomModel):
dataset_folder = models.ForeignKey(DatasetFolder, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
content_type = models.CharField(max_length=100)
size = models.PositiveIntegerField()
And from this polymorphic model, we have 3 inherit models for images, datasets, and relation files. A relation file it's file that described all relations between multiplay datasets ( if relations exist) (Can be one csv file without any relation, or can be some file like tables in DB that are connected to each other)
class DatasetRelation(OriginalFile):
file = models.FileField(max_length=500, upload_to=project_directory_path)
original_file_name = models.CharField(max_length=100)
class OriginalDataset(OriginalFile):
dataset_relation = models.ForeignKey(
DatasetRelation, on_delete=models.SET_NULL, blank=True, null=True
)
file = models.FileField(max_length=500, upload_to=project_directory_path)
original_file_name = models.CharField(max_length=100, null=True, blank=True)
table_name = models.CharField(max_length=100, null=True, blank=True)
rows_number = models.PositiveIntegerField()
dataset_metadata = models.JSONField()
class OriginalImage(OriginalFile):
original_file_name = models.CharField(max_length=100)
file = models.ImageField(max_length=500, upload_to=project_directory_path)
Now about the problem. If I just create project and after that delete it, all works fine. But if I upload file ( dataset folder and original_dataset instances created), and then I try to delete the project ( all inheritance instances should be deleted too) I got error:
AttributeError: 'NoneType' object has no attribute 'attname'
Full traceback:
2023-07-07T12:00:29.168850977Z Traceback (most recent call last):
2023-07-07T12:00:29.168858053Z File "/usr/local/lib/python3.9/site-packages/asgiref/sync.py", line 534, in thread_handler
2023-07-07T12:00:29.168865749Z raise exc_info[1]
2023-07-07T12:00:29.168871498Z File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 38, in inner
2023-07-07T12:00:29.168876303Z response = await get_response(request)
2023-07-07T12:00:29.168881665Z File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 233, in _get_response_async
2023-07-07T12:00:29.168887489Z response = await wrapped_callback(request, *callback_args, **callback_kwargs)
2023-07-07T12:00:29.168893254Z File "/usr/local/lib/python3.9/site-packages/asgiref/sync.py", line 479, in __call__
2023-07-07T12:00:29.168899697Z ret: _R = await loop.run_in_executor(
2023-07-07T12:00:29.168903449Z File "/usr/local/lib/python3.9/site-packages/asgiref/current_thread_executor.py", line 40, in run
2023-07-07T12:00:29.168907397Z result = self.fn(*self.args, **self.kwargs)
2023-07-07T12:00:29.168924991Z File "/usr/local/lib/python3.9/site-packages/asgiref/sync.py", line 538, in thread_handler
2023-07-07T12:00:29.168928691Z return func(*args, **kwargs)
2023-07-07T12:00:29.168932184Z File "/usr/local/lib/python3.9/contextlib.py", line 79, in inner
2023-07-07T12:00:29.168935815Z return func(*args, **kwds)
2023-07-07T12:00:29.168939356Z File "/usr/local/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
2023-07-07T12:00:29.168943047Z return view_func(*args, **kwargs)
2023-07-07T12:00:29.168946534Z File "/usr/local/lib/python3.9/site-packages/rest_framework/viewsets.py", line 125, in view
2023-07-07T12:00:29.168950276Z return self.dispatch(request, *args, **kwargs)
2023-07-07T12:00:29.168955073Z File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
2023-07-07T12:00:29.168961096Z response = self.handle_exception(exc)
2023-07-07T12:00:29.168966571Z File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
2023-07-07T12:00:29.168972964Z self.raise_uncaught_exception(exc)
2023-07-07T12:00:29.168978464Z File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
2023-07-07T12:00:29.168995178Z raise exc
2023-07-07T12:00:29.169001808Z File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
2023-07-07T12:00:29.169008146Z response = handler(request, *args, **kwargs)
2023-07-07T12:00:29.169013223Z File "/usr/local/lib/python3.9/site-packages/rest_framework/mixins.py", line 91, in destroy
2023-07-07T12:00:29.169019635Z self.perform_destroy(instance)
2023-07-07T12:00:29.169025352Z File "/usr/local/lib/python3.9/site-packages/rest_framework/mixins.py", line 95, in perform_destroy
2023-07-07T12:00:29.169031328Z instance.delete()
2023-07-07T12:00:29.169037074Z File "/usr/local/lib/python3.9/site-packages/django/db/models/base.py", line 966, in delete
2023-07-07T12:00:29.169043395Z collector.collect([self], keep_parents=keep_parents)
2023-07-07T12:00:29.169048678Z File "/usr/local/lib/python3.9/site-packages/django/db/models/deletion.py", line 297, in collect
2023-07-07T12:00:29.169054536Z field.remote_field.on_delete(self, field, sub_objs, self.using)
2023-07-07T12:00:29.169060804Z File "/usr/local/lib/python3.9/site-packages/django/db/models/deletion.py", line 24, in CASCADE
2023-07-07T12:00:29.169066836Z collector.collect(
2023-07-07T12:00:29.169073577Z File "/usr/local/lib/python3.9/site-packages/django/db/models/deletion.py", line 295, in collect
2023-07-07T12:00:29.169078650Z if sub_objs:
2023-07-07T12:00:29.169083662Z File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 284, in __bool__
2023-07-07T12:00:29.169088857Z self._fetch_all()
2023-07-07T12:00:29.169095209Z File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 1324, in _fetch_all
2023-07-07T12:00:29.169102496Z self._result_cache = list(self._iterable_class(self))
2023-07-07T12:00:29.169108867Z File "/usr/local/lib/python3.9/site-packages/polymorphic/query.py", line 64, in _polymorphic_iterator
2023-07-07T12:00:29.169114872Z real_results = self.queryset._get_real_instances(base_result_objects)
2023-07-07T12:00:29.169120061Z File "/usr/local/lib/python3.9/site-packages/polymorphic/query.py", line 390, in _get_real_instances
2023-07-07T12:00:29.169126018Z if base_object.polymorphic_ctype_id == self_model_class_id:
2023-07-07T12:00:29.169131806Z File "/usr/local/lib/python3.9/site-packages/django/db/models/query_utils.py", line 144, in __get__
2023-07-07T12:00:29.169137635Z instance.refresh_from_db(fields=[field_name])
2023-07-07T12:00:29.169142980Z File "/usr/local/lib/python3.9/site-packages/django/db/models/base.py", line 650, in refresh_from_db
2023-07-07T12:00:29.169149359Z db_instance = db_instance_qs.get()
2023-07-07T12:00:29.169155154Z File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 431, in get
2023-07-07T12:00:29.169160495Z num = len(clone)
2023-07-07T12:00:29.169170547Z File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 262, in __len__
2023-07-07T12:00:29.169177251Z self._fetch_all()
2023-07-07T12:00:29.169183088Z File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 1324, in _fetch_all
2023-07-07T12:00:29.169189447Z self._result_cache = list(self._iterable_class(self))
2023-07-07T12:00:29.169195989Z File "/usr/local/lib/python3.9/site-packages/polymorphic/query.py", line 64, in _polymorphic_iterator
2023-07-07T12:00:29.169201966Z real_results = self.queryset._get_real_instances(base_result_objects)
2023-07-07T12:00:29.169207735Z File "/usr/local/lib/python3.9/site-packages/polymorphic/query.py", line 457, in _get_real_instances
2023-07-07T12:00:29.169214069Z real_objects_dict = {
2023-07-07T12:00:29.169219539Z File "/usr/local/lib/python3.9/site-packages/polymorphic/query.py", line 458, in <dictcomp>
2023-07-07T12:00:29.169226109Z getattr(real_object, pk_name): real_object for real_object in real_objects
2023-07-07T12:00:29.169232278Z File "/usr/local/lib/python3.9/site-packages/django/db/models/query_utils.py", line 142, in __get__
2023-07-07T12:00:29.169238607Z val = self._check_parent_chain(instance)
2023-07-07T12:00:29.169244488Z File "/usr/local/lib/python3.9/site-packages/django/db/models/query_utils.py", line 158, in _check_parent_chain
2023-07-07T12:00:29.169251278Z return getattr(instance, link_field.attname)
2023-07-07T12:00:29.169257175Z AttributeError: 'NoneType' object has no attribute 'attname'
I use:
- django==3.2.14
- django-polymorphic==3.1.0
Maybe someone knows where is the problem and I can fix this. For now, I create a temporary fix but it's now perfect. Thanks for your help!
Hey there 👋 Are you able to write a test so we can reproduce this issue in the repo? That would be a big first step to getting this fixed. If it's not an issue for your project feel free to close this issue.