This question already has answers here:
What can I do about "ImportError: Cannot import name X" or "AttributeError: ... (most likely due to a circular import)"?
(17 answers)
Closed 3 years ago.
I got an error I don't understand !
cannot import name Item
In my model, I have items. These items are required for actions. But some of these items have an effect on actions :
items
from django.db import models
from effects.models import Effect
class Type(models.Model):
name = models.CharField(max_length=200)
def __unicode__(self):
return self.name
class Item(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length=200)
type = models.ForeignKey(Type)
quality = models.IntegerField()
effects = models.ManyToManyField(Effect,through='ItemEffect',blank=True)
item_requirement = models.ManyToManyField('self',through='ItemCraft',symmetrical=False,blank=True)
points = models.IntegerField()
def __unicode__(self):
return self.name
class Food(Item):
ap = models.IntegerField()
class Tool(Item):
durability = models.IntegerField()
[....]
class ItemEffect(models.Model):
item = models.ForeignKey(Item)
effect = models.ForeignKey(Effect)
def __unicode__(self):
return self.item.name+':'+str.lower(self.effect.name)
class Meta:
verbose_name_plural = 'items effects'
class ItemCraft(models.Model):
item = models.ForeignKey(Item,related_name='%(class)s_item_crafted')
item_requirement = models.ForeignKey(Item,related_name='%(class)s_item_required')
number = models.IntegerField()
def __unicode__(self):
return self.item.name+' requires '+str.lower(self.item.name)+'('+self.number+')'
class Meta:
verbose_name_plural = 'items crafts'
actions
from django.db import models
from items.models import Item
class Action(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length=200)
pa = models.IntegerField()
def __unicode__(self):
return self.name
class CraftAction(Action):
item = models.ForeignKey(Item)
def __unicode__(self):
return self.item.name+'\'s craft'
class Meta:
verbose_name_plural = 'crafts actions'
effects
from django.db import models
from actions.models import Action
class Effect(models.Model):
action = models.ForeignKey
class ApEffect(Effect):
ap = models.IntegerField()
There is a circular import in your code, that's why the Item can't be imported in action.
You can solve the problem by removing the import of a class in one of your files, and replacing it with a string containing the name of the class, as explained in the documentation. For example :
effects = models.ManyToManyField('effects.Effect',through='ItemEffect',blank=True)
Like madjar suggested, there is likely a circular import in your code. If you're having trouble finding out where the circle is (which modules and imports are involved), you can use the traceback option to get an idea of where the problem lies:
python manage.py validate --traceback
Edit - Validate is deprecated from django 1.7. So please run the following command -
python manage.py check --traceback
Try to import Locally your model instead of as public one, Example
def sample_function():
from effects.models import Effect # import within function or class
or import model as String -> 'APP_NAME.MODEL_NAME'
pay_methods = models.ManyToManyField('payment_app.AllowedPayMethod')
This was the first post that came up on Google so I will post this alternative cause of error.
In my code there was no circular imports, I solved this problem by manually deleting all .pyc files in my project. Apparently restarting the application wasn't recompiling my code.
Similar situation to Pythonator - I had an alternate cause for the same error message.
In my case, I had forgotten to activate the virtual environment I set up for my project and was trying to run the server. After activating the environment and running the server again I had no issues.
Related
I am developing a Django 2.0 project app. It has a (non-working) models.py file, which looks something like this:
from django.db import models
from django.utils import timezone
class Computer(models.Model):
name = models.CharField(max_length=25)
def __str__(self):
return "Computer {}".format(self.name)
class Software(models.Model):
name = models.CharField(max_length=25)
description = models.CharField(max_length=1024, blank=True)
def __str__(self):
return self.name
class SoftwareVersion(models.Model):
software = models.ForeignKey(Software, on_delete=models.CASCADE, related_name="versions")
version = models.CharField(max_length=100)
released_at = models.DateTimeField(default=timezone.now)
def __str__(self):
return "{} {}".format(self.software, self.version)
class ComputerSoftwareBundle(models.Model):
computer = models.ForeignKey(Computer, on_delete=models.CASCADE, related_name="bundles")
installed_at = models.DateTimeField(default=timezone.now)
versions = models.ManyToManyField(SoftwareVersion, through="BundleSoftwareVersion", related_name="bundles")
class BundleSoftwareVersion(models.Model):
bundle = models.ForeignKey(ComputerSoftwareBundle, on_delete=models.CASCADE)
version = models.ForeignKey(SoftwareVersion, on_delete=models.CASCADE)
class Meta:
unique_together = (("bundle", "version__software"),)
The app tracks software bundles currently or previously installed on computers. The thing here is that a bundle should not contain more than one version of the same software. Also, SoftwareVersion should contain a reference to Software, because the same version string has a different meaning for different pieces of software.
The code does not work as described in this Stackoverflow answer. I left the unique_together line in to illustrate what I am trying to achieve.
I've tried to work around this limitation of Django (not being able to use fields referred to via a foreign key in unique_together) by overriding the save and validate_unique methods in BundleSoftwareVersion but that did not work out completely well. Here's the implementation I have tried:
class BundleSoftwareVersion(models.Model):
bundle = models.ForeignKey(ComputerSoftwareBundle, on_delete=models.CASCADE)
version = models.ForeignKey(SoftwareVersion, on_delete=models.CASCADE)
def save(self, *args, **kwargs):
self.validate_unique()
super().save(*args, **kwargs)
def validate_unique(self, exclude=None):
super().validate_unique(exclude)
bundle_versions = BundleSoftwareVersion.objects.filter(bundle=self.bundle,
version__software=self.version.software)
count = len(bundle_versions)
if not self.pk:
# if this instance is not stored in the database,
# we need to increment the count to take this instance
# into account
count += 1
if count > 1:
raise ValidationError("There already is an instance of software '{}' in this bundle.".format(self.version.software))
I have thus far tried out these models via the admin site. The checks work when changing an existing ComputerSoftwareBundle (the admin site displays a message next to the offending entry), but adding results in an uncaught exception.
Is there a better way to enforce this kind of uniqueness?
I have come up with a workaround:
class BundleSoftwareVersion(models.Model):
bundle = models.ForeignKey(ComputerSoftwareBundle, on_delete=models.CASCADE)
version = models.ForeignKey(SoftwareVersion, on_delete=models.CASCADE)
_software = models.ForeignKey(Software, on_delete=models.CASCADE, null=True, editable=False)
class Meta:
unique_together = (("bundle", "_software"),)
def save(self, *args, **kwargs):
self._software = self.version.software
super().save(*args, **kwargs)
As you can see, I now have a helper field _software which is used in unique_together and into which the self.version.software is stored on each save.
So far, I have experienced one downside with this approach: trying to save a ComputerSoftwareBundle containing duplicate software instances results in an error page for IntegrityError being displayed instead of an error message within the form.
I would appreciate suggestions on how to fix this downside, or even suggestions for a different approach altogether.
my Django admin panel is showing object instead of self.name of the object.
I went through several similar questions here yet couldn't seem to resolve this issue. __unicode__ and __str__ bear the same results, both for books and for authors. I've changed those lines and added new authors/books in every change but no change.
MODELS.PY
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Author(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Book(models.Model):
auto_increment_id = models.AutoField(primary_key=True)
name = models.CharField('Book name', max_length=100)
author = models.ForeignKey(Author, blank=False, null=False)
contents = models.TextField('Contents', blank=False, null=False)
def __unicode__(self):
return self.name
I used both unicode & str interchangeably, same result.
Here are the screenshots of the admin panel by menu/action.
1st screen
Author List
Single Author
Your indentation is incorrect. You need to indent the code to make it a method of your model. It should be:
class Author(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
If you are using Python 3, use __str__. If you are using Python 2, use __unicode__, or decorate your class with the python_2_unicode_compatible decorator. After changing the code, make sure you restart the server so that code changes take effect.
So I am trying to create a custom Manager that extends the default one and I am getting an error that for the life of me I cannot fix. I've read all the django docs and can't see what I've done wrong!
ERROR:
NameError at /
name 'article_finish_date' is not defined
Here is my models.py
import datetime
from django.conf import settings
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class ArticleManager(models.Manager):
def get_queryset(self):
return super(ArticleManager, self).get_queryset().filter(article_finish_date==None)
class Article(models.Model):
article_name_text = models.CharField(max_length=200)
article_creation_date = models.DateTimeField('date created')
article_publish_date = models.DateTimeField('date published', null=True, blank=True)
article_finish_date = models.DateTimeField('date finished', null=True, blank=True)
def __str__(self):
return self.article_name_text
actives = ArticleManager()
I have tried filtering by all the different values of the Article model, however the same issue occurs. I have tried both migrated and makemigrations, however no progress has been made.
Many thanks in advance, ask if you need more details!
The error is in this part:
.filter(article_finish_date==None)
Python is trying to evaluate the expression article_finish_date==None, except article_finish_date hasn't been defined yet. Instead, you want to use a single =
.filter(article_finish_date=None)
I am a Django newbie and working on admin section of my project. Below is my code for models.py.
class Shops(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length=1500)
address = models.CharField(max_length=1000)
location = models.CharField(max_length=100)
contact_number = models.IntegerField()
other_details = models.CharField(max_length=100,null='true')
def __str__(self): # __unicode__ on Python 2
return (self.name)
class Shop_Type(models.Model):
category = models.CharField(max_length=500)
def __str__(self): # __unicode__ on Python 2
return (self.category)
class Shop_Category(models.Model):
shop_id = models.ForeignKey(Shops)
category_id = models.ForeignKey(Shop_Type)
Now I want to display option for inserting data in both "Shops" and "Shop_Category" tables from the single page of admin module as both of them are connected. I referred this question but failed to achieve what I want. Below is the code for admin.py I used:
class ShopCatAdmin(admin.ModelAdmin):
model = Shop_category
class ShopsAdmin(admin.ModelAdmin):
inlines = [ShopCatAdmin]
admin.site.register(Shops, ShopsAdmin)
It is throwing some attribute error saying that - "'ShopCatAdmin' object has no attribute 'get_formset'"
It would be great if anyone can help me out with this.
Thanks in advance :)
You need to define ShopCatAdmin as inheriting from an inline admin class, not the basic admin.
class ShopCatAdmin(admin.TabularInline):
model = Shop_Category
(Note, Python style discourages underscores in class names; your models should be called ShopType and ShopCategory.)
When I try to migrate my code I get this error.
Here are my code and classes:
from django.db import models
from core.models import Event
class TicketType(models.Model):
name = models.CharField(max_length=45)
price = models.DecimalField(max_length=2, decimal_places=2, max_digits=2)
type = models.CharField(max_length=45)
amount = models.IntegerField()
event = models.ForeignKey(Event)
class Meta:
app_label = "core"
import datetime
from django.core.serializers import json
from django.db import models
from core.models import User
class Event(models.Model):
page_attribute = models.TextField()
name = models.TextField(max_length=128 , default="New Event")
description = models.TextField(default="")
type = models.TextField(max_length=16)
age_limit = models.IntegerField(default=0)
end_date = models.DateTimeField(default=datetime.datetime.now())
start_date = models.DateTimeField(default=datetime.datetime.now())
is_active = models.BooleanField(default=False)
user = models.ForeignKey(User)
ticket_type=models.ForeignKey('core.models.ticket_type.TicketType')
class Meta:
app_label = "core"
Here is the error I get:
CommandError: One or more models did not validate:
core.event: 'ticket_type' has a relation with model core.models.ticket_type.TicketType,
which has either not been installed or is abstract.
You're unnecessarily confusing yourself by having these in separate files within the same app.
But your issue is caused by the way you're referenced the target model. You don't use the full module path to the model: you just use 'app_name.ModelName'. So in your case it should be:
ticket_type=models.ForeignKey('core.TicketType')
Another issue can be when using multiple models in separate files missing statement like:
class Meta:
app_label = 'core_backend'
You can also get this error if there a bug in your models file that prevents it from loading properly. For example, in models.py
from third_party_module_i_havent_installed import some_method
I hit this error when I didn't put a third-party app in my INSTALLED_APPS setting yet.