4
class B(models.Model):
    whatever = models.TextField(blank=True)

    @staticmethod
    def are_we_ok():
        return False

class A(models.Model)
    text = models.TextField(blank=True)

    @staticmethod
    def is_everything_ok():
        if not B.are_we_ok():
            raise B.DoesNotExist




A.is_everything_ok()

Why I'm getting error:

File "asdf/models.py", line x, in is_everything_ok
    if not B.are_we_ok():

AttributeError: 'NoneType' object has no attribute 'are_we_ok'

However if I do:

class A(models.Model)
    text = models.TextField(blank=True)

    @staticmethod
    def is_everything_ok():
        from asdf.models import B
        if not B.are_we_ok():
            raise B.DoesNotExist

it works. This doesn't make any sense to me. This is part of huge Django app. Any ideas what kind situation could cause this? (is circular dependency possible for example?)

Update:

What I forgot to mention that this code has been running four years in production without any troubles. Just some recent unrelated edits triggered this error.

xoopp
  • 91
  • 1
  • 4

2 Answers2

1

Replace @staticmethod with @classmethod. With staticmethod, neither self or the class are passed as the first argument, which is why you can't call the method.

If you switch, you'll need to add the class as the first argument to your function:

class B(models.Model):
    whatever = models.TextField(blank=True)

    @classmethod
    def are_we_ok(cls):
        return False

See: What is the difference between @staticmethod and @classmethod in Python? for more information.

Community
  • 1
  • 1
Brandon Taylor
  • 33,823
  • 15
  • 104
  • 144
  • But why the staticmethod is problem here? As you can see, there's staticmethod calling staticmethod. It shouldn't require that there's anything passed as first argument? – xoopp Feb 28 '14 at 14:03
  • Technically, it shouldn't be a problem. staticmethod can be called on the class itself, or an instance of the class. This is working for me in Python 2.7.5 – Brandon Taylor Feb 28 '14 at 14:17
0

Reason for this was circular import. I refactored models to models package instead of massive models.py file and was able to get rid of this.

I wonder why Django/Python allows this kind of "flexibility". I know Python is not Java but this just doesn't happen with Java.

xoopp
  • 91
  • 1
  • 4