Hom*_*lli 6 python django django-models
我正在使用 Django 3.2,并且遇到了一个问题,似乎在这里和这里也有答案,并且我已经尝试了接受的答案中提供的解决方案,但无法解决我遇到的问题(错误消息在主题标题中)。
这是我的模型的样子:
#### models.py
class ActionableModel:
    def __init__(self, child_object):
        self.child = child_object
        # FIX: This might be an expensive operation ... need to investigate
        if isinstance(child_object, django.contrib.auth.get_user_model()):
            self.owner = child_object
            self.actionable_object = child_object
        else:
            self.owner = child_object.get_owner()
            self.actionable_object = child_object.get_actionable_object()
        self.owner_id = self.owner.id
        
        self.ct = ContentType.objects.get_for_model(self.actionable_object)
        self.object_id = self.actionable_object.id
    # ...
class Prey(models.Model):
    # ... fields
    pass
class Predator(models.Model, ActionableModel):
    catches = GenericRelation(Prey)
    catch_count = models.PositiveIntegerField(default=0, db_index=True)
    last_catch = models.DateTimeField(editable=False, blank=True, null=True, default=None)
     
    def __init__(self, *args, **kwargs):
        ActionableModel.__init__(self, *args, **kwargs)  
    # ...
    
    class Meta:
        abstract = True
# Classes used for testing - naming similar to [mommy](https://model-mommy.readthedocs.io/en/latest/basic_usage.html)
class Daddy():
    
    def __init__(self, *args, **kwargs):
        ActionableModel.__init__(self, *args, **kwargs)      
class Foo(Daddy, Predator):
    # ...
    pass
在 shell 中,我输入以下内容:
from myapp.models import Foo
admin = django.contrib.auth.get_user_model().objects.all().first()
foo = Foo.objects.create(child_object=admin)
以下是导致主题标题的错误的堆栈跟踪:
Foo.objects.create(child_object=admin)                                                                            
Traceback (most recent call last):                                                                                                            
  File "<console>", line 1, in <module>                                                                                                       
  File "/path/to/myapp/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/myapp/env/lib/python3.8/site-packages/django/db/models/query.py", line 453, in create
    obj.save(force_insert=True, using=self.db)
  File "/path/to/myapp/env/lib/python3.8/site-packages/django/db/models/base.py", line 726, in save
    self.save_base(using=using, force_insert=force_insert,
  File "/path/to/myapp/env/lib/python3.8/site-packages/django/db/models/base.py", line 763, in save_base
    updated = self._save_table(
  File "/path/to/myapp/env/lib/python3.8/site-packages/django/db/models/base.py", line 822, in _save_table
    pk_val = self._get_pk_val(meta) 
  File "/path/to/myapp/env/lib/python3.8/site-packages/django/db/models/base.py", line 575, in _get_pk_val
    return getattr(self, meta.pk.attname)
  File "/path/to/myapp/env/lib/python3.8/site-packages/django/db/models/query_utils.py", line 148, in __get__
    val = self._check_parent_chain(instance)
  File "/path/to/myapp/env/lib/python3.8/site-packages/django/db/models/query_utils.py", line 164, in _check_parent_chain
    return getattr(instance, link_field.attname)
AttributeError: 'NoneType' object has no attribute 'attname'
是什么导致了这个错误,我该如何解决它?
问题似乎是__init__djangoModel类中的方法永远不会被调用。这是因为__init__在派生类中定义了方法,但未super()显式调用该方法。
需要两件事:
super。super到达Model.__init__方法。将这些要点应用到提供的源代码中:
class ActionableModel:
    def __init__(self, child_object, *args, **kwargs):
        # need to call super here
        super().__init__(*args, **kwargs)
        self.child = child_object
        ...
class Prey(models.Model):
    pass
class Predator(ActionableModel, models.Model):
    catches = GenericRelation(Prey)
    ...    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)  
class Daddy:        
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)      
class Foo(Daddy, Predator):
    pass