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(...):
...