Consider these two styles of code that accomplish the same thing:

Nested imports


from django.db.models import *

class SmallAutoField(fields.AutoField):
    def db_type(self, connection):
        return "smallserial"


from common import models

class Test(models.Model):
    id = models.SmallAutoField()
    test = models.IntegerField()

Separate imports


from django.db import models

class SmallAutoField(models.fields.AutoField):
    def db_type(self, connection):
        return "smallserial"


from django.db import models
from common import models as my_models

class Test(models.Model):
    id = my_models.SmallAutoField()
    test = models.IntegerField()

I know which version I prefer stylistically, but which version is the proper way to do it and why?

As for performance: I tried to timeit the Nested version, but that's not possible because SyntaxError: import * only allowed at module level. So, is there another way to benchmark this method?

Bytecode for reference, but doesn't look like it tells much:

>>> dis.dis('from django.db.models import *')
  1           0 LOAD_CONST               0 (0)
              3 LOAD_CONST               1 (('*',))
              6 IMPORT_NAME              0 (django.db.models)
              9 IMPORT_STAR
             10 LOAD_CONST               2 (None)
             13 RETURN_VALUE
>>> dis.dis('from django.db import models')
  1           0 LOAD_CONST               0 (0)
              3 LOAD_CONST               1 (('models',))
              6 IMPORT_NAME              0 (django.db)
              9 IMPORT_FROM              1 (models)
             12 STORE_NAME               1 (models)
             15 POP_TOP
             16 LOAD_CONST               2 (None)
             19 RETURN_VALUE
  • 4
    The difference in computational overhead is almost certainly inconsequential. The "proper" way to do it is going to depend on whether or not you want to be explicit or implicit. – Robert Harvey Nov 21 '16 at 17:44
  • @RobertHarvey On IRC, I got multiple guys preaching to me not to use import * here. I do prefer the implicit method, so are you saying that it's ok to use it after all? – dvtan Nov 22 '16 at 19:24
  • Did you ask the IRC folks why they prefer you to not use import *? – Robert Harvey Nov 22 '16 at 19:38
  • @RobertHarvey I did, their answer wasn't worth remembering. It was a form of regurgitating bad practice, polluting namespace, etc. None of which applies because I'm deliberately taking in everything available from django.db.models, effectively "decorating" it if you will. But that's just my novice opinion. – dvtan Nov 22 '16 at 19:44
  • 1
    Then I guess you have your answer. – Robert Harvey Nov 22 '16 at 19:45

The class SmallAutoField is actually an innovation created for this particular application - it's an improvement. It "moves the ball down the field" so to speak, upgrading the ability to describe persistence.

For a new reader of the program years from now (e.g. an engineer who needs to understand what it does) the intent of the second style is slightly clearer overall: they can easily see that "models" refers to to Django.db.models and "my_models" to something new.

The second style, highlights the credit awarded for the innovation by calling it "my_models." It might be good to highlight the intent further like "serial_id_models" or "advanced_models."

HTH -- Rich

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.