You are on page 1of 4

I am using django 3.2.

I am writing a social app, which necessitates (makes necessary) the use of multiple
inheritance. I am having a problem with one of the inheritable models, in that when
I inherit from that model, I can't delete instances of the derived (child) class.

Code (relevant parts only):


=============================

class Actionable:

def __init__(self, *args, **kwargs):


self.owner = None
self.owner_id = None
self.actionable_object = None
self.ct = None
self.object_id = None

self.is_setup = False

def setup_variables(self, args):


if not self.is_setup:
self.owner = args['owner']
self.owner_id = args['owner_id']
self.actionable_object = args['actionable_object']
self.ct = args['ct']
self.object_id = args['object_id']

self.is_setup = True

# This MUST be implemented by ALL CONCRETE sub classes


@abstractmethod
def get_actionable_object(self):
raise NotImplementedError("Subclasses MUST implement
get_actionable_object()")

# This MUST be implemented by ALL CONCRETE sub classes


@abstractmethod
def get_owner(self):
raise NotImplementedError("Subclasses MUST implement get_owner()")

# ....

class SocialActivity(models.Model):
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE,
db_index=True,
related_name='%(app_label)s_%
(class)s_content_types',
related_query_name='%(app_label)s_%
(class)s_content_type')
object_id = models.PositiveIntegerField(db_index=True)
content_object = GenericForeignKey('content_type', 'object_id')
actor = models.ForeignKey(User, blank=False, null=False,
on_delete=models.CASCADE,
related_name='%(app_label)s_%(class)s_users',
related_query_name='%(app_label)s_%(class)s_user')
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return f"SocialActivity: {self.content_type.name}, {self.object_id},
{self.actor.username}, {datetime.strftime(self.created_at,'%Y-%B-%d %H:%M:%s')} "

class Meta:
abstract = True
constraints = [
models.UniqueConstraint(fields=['content_type',
'object_id', 'actor'],
name="%(app_label)s_%(class)s_user_unique")
]

class SocialMediaSharingPlatform(models.Model):
name = models.CharField(max_length=64, unique=True)
endpoint = models.URLField()
post_params = JSONField()
functor = models.TextField()

class SocialMediaShareDefinition(SocialActivity):
platform = models.ForeignKey(SocialMediaSharingPlatform, blank=False,
null=False, on_delete=models.CASCADE,
related_name='%(app_label)s_%
(class)s_social_media_shares',
related_query_name='%(app_label)s_%
(class)s_social_media_share')
class Meta:
constraints = [
models.UniqueConstraint(
fields=['platform','actor','content_type','object_id'],
name='unique_user_socialmedia_share'
)
] + SocialActivity.Meta.constraints

# These are entries for the actual shares


class SocialMediaShare(models.Model):
definition = models.ForeignKey(SocialMediaShareDefinition,
on_delete=models.CASCADE)
utr_key = models.CharField(max_length=10, help_text=_('key that allows share to
be tracked'), unique=True)
created_at = models.DateTimeField(auto_now=True, db_index=True)

class Meta:
ordering = ('-created_at',)

class SocialMediaShareable(models.Model, Actionable):


socialmediashares = GenericRelation(SocialMediaShare)

def __init__(self, *args, **kwargs):


super(SocialMediaShareable,self).__init__(*args, **kwargs)

def get_absolute_url(self):
return NotImplementedError("Subclasses of SocialMediaShareable must
implement an get_absolute_url() method!")

# ...

class Meta:
abstract = True

Instantiating SocialObjectDaddy and then attempting to delete


==============================================================

from django.contrib.auth import get_user_model as gum


from social.models import SocialObjectDaddy as SOD

me = gum().objects.get(id=1)
sod = SOD.objects.create(user=me)

sod.delete() # <- barfs here

Error stack trace


Field: social.SocialObjectDaddy.socialmediashares #
print statement in deletion.py
Field: social.SocialObjectDaddy.socialmediashares has bulk related fields #
print statement in deletion.py
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/path/to/proj-folder/env/lib/python3.8/site-packages/django/db/models/
base.py", line 953, in delete
collector.collect([self], keep_parents=keep_parents)
File "/path/to/proj-folder/env/lib/python3.8/site-packages/django/db/models/
deletion.py", line 320, in collect
sub_objs = field.bulk_related_objects(new_objs, self.using)
File "/path/to/proj-folder/env/lib/python3.8/site-packages/django/contrib/
contenttypes/fields.py", line 480, in bulk_related_objects
return self.remote_field.model._base_manager.db_manager(using).filter(**{
File "/path/to/proj-folder/env/lib/python3.8/site-packages/django/db/models/
manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/path/to/proj-folder/env/lib/python3.8/site-packages/django/db/models/
query.py", line 941, in filter
return self._filter_or_exclude(False, args, kwargs)
File "/path/to/proj-folder/env/lib/python3.8/site-packages/django/db/models/
query.py", line 961, in _filter_or_exclude
clone._filter_or_exclude_inplace(negate, args, kwargs)
File "/path/to/proj-folder/env/lib/python3.8/site-packages/django/db/models/
query.py", line 968, in _filter_or_exclude_inplace
self._query.add_q(Q(*args, **kwargs))
File "/path/to/proj-folder/env/lib/python3.8/site-packages/django/db/models/sql/
query.py", line 1396, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/path/to/proj-folder/env/lib/python3.8/site-packages/django/db/models/sql/
query.py", line 1415, in _add_q
child_clause, needed_inner = self.build_filter(
File "/path/to/proj-folder/env/lib/python3.8/site-packages/django/db/models/sql/
query.py", line 1289, in build_filter
lookups, parts, reffed_expression = self.solve_lookup_type(arg)
File "/path/to/proj-folder/env/lib/python3.8/site-packages/django/db/models/sql/
query.py", line 1115, in solve_lookup_type
_, field, _, lookup_parts = self.names_to_path(lookup_splitted,
self.get_meta())
File "/path/to/proj-folder/env/lib/python3.8/site-packages/django/db/models/sql/
query.py", line 1542, in names_to_path
raise FieldError("Cannot resolve keyword '%s' into field. "
django.core.exceptions.FieldError: Cannot resolve keyword 'content_type' into
field. Choices are: created_at, definition, definition_id, id,
socialmediainboundvisit, utr_key
Why is this exception being thrown? - and how do I fix it.

This is probably something trivial, but I have been staring the code for days, so
could do with another set of eyes to point out where I'm going wrong.

You might also like