How to refer back to the model from utils.py in a Django object

I'm trying to create a field in a django model, that forces a unique value in the model. I'm using utils.py to generate the value.

The error I get is:

File "/Users/evancutler/PycharmProjects/DjangoProject1/MCARS/utils.py", line 2, in <module>
    from MCARS.models import Profile
ImportError: cannot import name 'Profile' from partially initialized module 'MCARS.models' (most likely due to a circular import) (/Users/evancutler/PycharmProjects/DjangoProject1/MCARS/models.py)

Here's my model:

class Profile(models.Model):

    # Managed fields
    user     = models.OneToOneField(User, related_name="profile", on_delete=models.CASCADE)
    memberid = models.CharField(
            max_length = 10,
            blank=True,
            editable=True,
            unique=True,
            default=utils.create_new_ref_number()
        )
    avatar   = models.ImageField(upload_to="static/mcars/img/avatars", null=True, blank=True)
    birthday = models.DateField(null=True, blank=True)
    gender   = models.CharField(max_length=10, choices=constants.GENDER_CHOICES, null=True, blank=True)
    invited  = models.BooleanField(default=False)
    registered = models.BooleanField(default=False)
    height   = models.PositiveSmallIntegerField(null=True, blank=True)
    phone    = models.CharField(max_length=32, null=True, blank=True)
    address  = models.CharField(max_length=255, null=True, blank=True)
    number   = models.CharField(max_length=32, null=True, blank=True)
    city     = models.CharField(max_length=50, null=True, blank=True)
    zip      = models.CharField(max_length=30, null=True, blank=True)

here's my utils:

import random
from MCARS.models import Profile

def create_new_ref_number():
    not_unique = True
    while not_unique:
        unique_ref = random.randint(1000000000, 9999999999)
        if not Profile.objects.filter(memberid=unique_ref):
            not_unique = False
    return str(unique_ref)

how do I tell the utils.py to refer back to the model to check if the value is unique and if not, to try again?

Thanks!

NOTE: First of all, generating random IDs like this is a highly inefficient way. You'll run into a lot of problems later on as the number of members grow. Django automatically assigns a unique id to each model object. You should be using that.


Now, to answer your question: You're running into the circular import problem.

The solution is to keep the create_new_ref_number function in the same file as your model.

Another issue I noticed is that you're calling the function when passing it to the default argument. Correct way is to pass the name of the function without parenthesis (i.e. create_new_ref_number without ()) and Django will call it when needed.

Example:

# models.py
class Profile(...):
    memberid = models.CharField(
            ...
            default=create_new_ref_number # IMPORTANT: no parentheses i.e. no ()
        )

# function stays in the same file as the model
def create_new_ref_number(...):
    ...
Вернуться на верх