Reputation: 145
My Django-Project uses Three Apps, chat, user, sowi
. Every App having models structured in the following way. I'm getting an error when starting the Server, i think it is because i have circular Imports. How do i fix this issue?
chat/models.py
from user.models import User
class Chat(models.Model):
name = models.CharField(max_length=100, default="private")
class Message(models.Model):
sender = models.ForeignKey(User, on_delete=models.CASCADE)
receiver = models.ForeignKey(Chat, on_delete=models.CASCADE)
user/models.py
from chat.models import Chat
from sowi.models import Sowi
class User(AbstractUser):
chats = models.ManyToManyField(Chat, blank=True)
subscriptions = models.ManyToManyField(Sowi, related_name="subscriptions", blank=True)
memberships = models.ManyToManyField(Sowi, related_name="memberships", blank=True)
blocked = models.ManyToManyField("self", related_name="blocked", blank=True)
sowi/models.py
from chat.models import Chat, Message
from user.models import User
class Sowi(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
chat = models.OneToOneField(Chat, blank=True, null=True, on_delete=models.CASCADE)
Error Message:
File "*/sowi/models.py", line 9, in <module>
from chat.models import Chat, Message
File "*/chat/models.py", line 4, in <module>
from user.models import User
File "*/user/models.py", line 5, in <module>
from chat.models import Chat
ImportError: cannot import name 'Chat' from 'chat.models'
Thanks in Advance!
Upvotes: 0
Views: 3076
Reputation: 476604
It is better to refer to models with string literals, than to refer to it with references to the model class. Django can handle this and will automatically resolve these:
# chat/models.py
from django.db import models
class Chat(models.Model):
name = models.CharField(max_length=100, default="private")
class Message(models.Model):
sender = models.ForeignKey('user.User', on_delete=models.CASCADE)
receiver = models.ForeignKey(Chat, on_delete=models.CASCADE)
# user/models.py
from django.db import models
class User(AbstractUser):
chats = models.ManyToManyField(Chat, blank=True)
subscriptions = models.ManyToManyField('sowi.Sowi', related_name="subscriptions", blank=True)
memberships = models.ManyToManyField('sowi.Sowi', related_name="memberships", blank=True)
blocked = models.ManyToManyField("self", related_name="blocked", blank=True)
# sowi/models.py
from django.db import models
class Sowi(models.Model):
owner = models.ForeignKey('user.User', on_delete=models.CASCADE)
chat = models.OneToOneField('chat.Chat', blank=True, null=True, on_delete=models.CASCADE)
It is even better when you reference the user model [Django-doc] to set the AUTH_USER_MODEL
setting [Django-doc], and use this setting, such that if you later change your mind, you can more conveniently change this:
# chat/models.py
from django.conf import settings
from django.db import models
class Chat(models.Model):
name = models.CharField(max_length=100, default="private")
class Message(models.Model):
sender = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
receiver = models.ForeignKey(Chat, on_delete=models.CASCADE)
# user/models.py
from django.db import models
class User(AbstractUser):
chats = models.ManyToManyField(Chat, blank=True)
subscriptions = models.ManyToManyField('sowi.Sowi', related_name="subscriptions", blank=True)
memberships = models.ManyToManyField('sowi.Sowi', related_name="memberships", blank=True)
blocked = models.ManyToManyField("self", related_name="blocked", blank=True)
# sowi/models.py
from django.conf import settings
from django.db import models
class Sowi(models.Model):
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
chat = models.OneToOneField('chat.Chat'
Upvotes: 6
Reputation: 524
try:
class User(AbstractUser):
chats = models.ManyToManyField('chat.Chat', blank=True)
subscriptions = models.ManyToManyField('sowi.Sowi', related_name="subscriptions", blank=True)
memberships = models.ManyToManyField('sowi.Sowi', related_name="memberships", blank=True)
blocked = models.ManyToManyField("self", related_name="blocked", blank=True)
The problem with your code is that you're importing Chat
and Sowi
in user models.py
, and then you're trying to import user models
in Chat
and Sowi
. You see the Circular Import there?
Upvotes: 3