I'm trying to import a model from another Django app in my project. However, when I try to import, I keep getting an error for:
ImportError No module named trunk.profiles.models.
However, when I cmnd click on the model on my IDE it takes me to the model. So it recognizes where the model is coming from, but I think for some reason Django is not recognizing the path.
Here is my code from my models.py which I'm trying to import another model, Profiles from a different Django app:
from django.db import models
from trunk.profiles.models import Profiles # source of error
class ContentObject(models.Model):
course_name = models.CharField(max_length15)
course_topic = models.CharField(max_length = 30)
op_UserName = models.ForeignKey(Profiles)
Add trunk.profiles to Your INSTALLED_APPS
settings.py
INSTALLED_APPS = [
...
'trunk.profiles'
]
TIP
Instead of import model, specify a model with the full application label
from django.db import models
class ContentObject(models.Model):
course_name = models.CharField(max_length15)
course_topic = models.CharField(max_length = 30)
op_UserName = models.ForeignKey('trunk.profiles.Profiles')
Related
I am using wagtails wagtail-generic-chooser to create customChoosers for my data models and it is working great whenever I am referencing other modelAdmin models.
However, I have come across a situation where I have a Lexis model with a field that has a FK link to itself. The idea is to have a Lexis term, and then there can be related lexis terms connected to it. It works fine with a normal FieldPanel but this isn't a very good UI experience when there are hundreds of lexis terms. Accordingly, I wanted to create a custom LexisChooser for this field. However, the issue I've run into is according to the documentation in order to create a functional widget, I am required to create both a view and adminChooser that references the model the ChooserPanel is connected to.
https://github.com/wagtail/wagtail-generic-chooser#chooser-widgets-model-based
This makes sense, however, when I then try to import my LexisChooser into my Lexis model to use the LexisChooser as a widget, I get the error below.
ImportError: cannot import name 'Lexis' from 'lexis.models'
I realize this is due to a circular import error issue because I have subclasses that are importing the Lexis Class in order to build the LexisChooser widget and then I am trying to import that widget into the Lexis Class.
I know this isn't a bug with Wagtail nor is it a problem with wagtail-generic-chooser, However, does anyone have any idea how I can refactor the code to make this function so that I can use a LexisChooser on a field of the Lexis Model.
Below is my code.
views.py create a view
from django.utils.translation import ugettext_lazy as _
from generic_chooser.views import ModelChooserViewSet
from lexis.models import Lexis
class LexisChooserViewSet(ModelChooserViewSet):
icon = 'user'
model = Lexis
page_title = _("Choose A Lexis Term")
per_page = 20
order_by = 'term'
fields = ['term']
wagtail_hooks.py register view
from wagtail.core import hooks
from .views import LexisChooserViewSet
#hooks.register('register_admin_viewset')
def register_lexis_chooser_viewset():
return LexisChooserViewSet('lexis_chooser', url_prefix='lexis-chooser')
widgets.py create a widget
from django.utils.translation import ugettext_lazy as _
from generic_chooser.widgets import AdminChooser
from lexis.models import Lexis
class LexisChooser(AdminChooser):
choose_one_text = _('Choose a Lexis')
choose_another_text = _('Choose another Lexis')
link_to_chosen_text = _('Edit this Lexis')
model = Lexis
choose_modal_url_name = 'lexis_chooser:choose'
lexis/models.py use widget
from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.admin.edit_handlers import FieldPanel, InlinePanel
from wagtail.core.models import Orderable
from modelcluster.models import ClusterableModel
from chooser_panels.widgets import LexisChooser
# Orderable link to multiple other linked lexis terms
class LexisLink(Orderable):
page = ParentalKey("lexis.Lexis", related_name="lexis_link")
term_link = models.ForeignKey(
'lexis.Lexis',
on_delete=models.SET_NULL,
related_name='term_linked',
null=True
)
panels = [
FieldPanel("term_link", widget=LexisChooser)
]
class Lexis(ClusterableModel):
template = "lexis/lexis_page.html"
term = models.CharField(max_length=100, blank=True, null=True)
panels = [
FieldPanel("term"),
InlinePanel('lexis_link', label='Linked Lexis Terms'),
]
def __str__(self):
return self.term
class Meta:
verbose_name = "Lexis"
verbose_name_plural = "Lexis"
This, unfortunately, results in a circular import error:
ImportError: cannot import name 'Lexis' from 'lexis.models'
On researching this error, I found that people recommend importing Lexis within the class as required rather than at the top of each file, but that doesn't seem to work with the subclassing as outlined above, because I get the same error.
If you have any ideas on how I can refactor the code to make it work and not create the circular import error it would be much appreciated.
I am running
Django 3,
python 3.7,
wagtail 2.8
Thank you
Split your models file into two separate files containing Lexis and LexisLink, as demonstrated in the documentation.
Then LexisLink can refer to LexisChooser while it cleanly refers to the Lexis model.
I want to use my model file from my database by importing it in views.py. But I get an error when I call a class from models.py.
ERROR: ImportError: cannot import name Vehicle
My path:
+ vehicle
---> __init__.py
---> models.py
---> views.py
vehicle/models.py
from __future__ import unicode_literals
from django.db import models
class Vehicle(models.Model):
id = models.BigAutoField(primary_key=True)
plate = models.TextField()
driver = models.ForeignKey(Driver, models.DO_NOTHING)
class Meta:
managed = False
db_table = 'vehicle'
Vehicle/views.py
from vehicle.models import Vehicle
s = Vehicle.objects.all()
print s
If you are calling model in view, you can call it directly
from model import Vehicles
If you want to have a full path, you can add the location of vehicles on your Path
import sys
sys.path.insert(0, 'path_to_vehicle_folder')
from vehicles.model import Vehicles
The way you are doing now, assumes that your execution happens outside vehicles directlory
vehicles\
__init__.py
model.py
view.py
this.py
In this.py you can import as you did.
You can always execute print(sys.path), to see where your python is going to look for packages/modules :) with the sys.path.insert, we add a location we want to include when looking for modules. There exists better ways :)
I'm currently working on an large Django project (version 1.10.7) and am running into an error with a model field in a sub-application. Here's what the basic structure looks like:
project/
app_one/
__init__.py
apps.py
models.py
urls.py
views.py
app_two/
__init__.py
apps.py
models.py
urls.py
views.py
The model and field in question looks like this (project/app_one/app_two/models.py):
class SampleModel(model.Model):
parent = models.ForeignKey('self', null=True, blank=True, related_name='members')
When I run python manage.py makemigrations app_one.app_two in the root folder I get this error message:
File .../django/db/models/utils.py", line 23, in make_model_tuple
"must be of the form 'app_label.ModelName'." % model ValueError: Invalid model reference 'app_one.app_two.SampleModel'. String model
references must be of the form 'app_label.ModelName'.
Here is code from other files that are relevant:
project/settings.py:
INSTALLED_APPS = filter(None, (
...
'app_one',
'app_one.app_two',
...
)
project/app_one/app_two/apps.py:
from __future__ import unicode_literals
from django.apps import AppConfig
class AppOneAppTwoConfig(AppConfig):
name = 'app_one.app_two'
label = 'app_one.app_two'
project/app_one/app_two/__init__.py:
default_app_config = 'app_one.app_two.apps.AppOneAppTwoConfig'
I believe the error here is that Django is only looking for one . in the full model name (app_one.app_two.SampleModel) to separate the app label from the model name in django/db/models/utils.py, and since there are two in this case, it fails.
My question is: This seems like a weird for Django not to account for...is there anyway to retain the dot notation of the app label and still have a self-referencing ForeignKey in a sub-application?
As you mention, it seems to be a lookup error when the project is trying to locate your app due to the nested apps. This can be solved by specifying the app name with an app_label in the models internal meta class:
class SampleModel(models.Model):
...
class Meta:
app_label = 'app_two'
I was able to solve this by changing the app_label to 'app_one_app_two' in apps.py. Because django references this when registering the related models, it doesn't break. All migrations are then registered under that label as well.
I am writing my first Django project and using Django 1.7, and for my login and authentication I am using the Django User model. I am now creating my models. Project and User share a Many-to-Many relationship
models.py:
from django.db import models
from django import forms
from django.contrib.auth.models import User
class Project(models.Model):
project_name = models.CharField(max_length=128, unique = True)
project_description = models.CharField(max_length=128)
users_annotating = models.ManyToManyField(User)
However, I get this error when I try to migrate:
ValueError: Related model 'auth.User' cannot be resolved
Does anyone understand this problem?
I'm guessing that you have
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
in your newly created Django 1.7 migration.
If you comment out that dependency and just in case replace it with
dependencies = [
('auth', '__first__'),
]
things should work.
I'm attempting to work my way through Practical Django Projects. It seems to be a bit old, but I've manage to convert the code up to this point.
At this point the book would like me to change my models.py to be this:
class SearchKeyword(models.Model)
keyword = models.CharField(maxlength=50, core=True)
page = models.ForeignKey(FlatPage, edit_inline=models.STACKED,
min_num_in_admin=3, num_extra_on_change=1)
I know that this is now done in the admin.py instead. So my models.py looks like this:
from django.db import models
from django.contrib.flatpages.models import FlatPage
class SearchKeyword(models.Model):
keyword = models.CharField(max_length=50)
page = models.ForeignKey(FlatPage)
class Admin:
pass
def __unicode__(self):
return self.keyword
And the admin.py I've created now looks like this:
from search.models import SearchKeyword
from django.contrib import admin
from django.contrib.flatpages.models import FlatPage
class SearchKeywordInline(admin.StackedInline):
model = SearchKeyword
extra = 3
class FlatPageAdmin(admin.ModelAdmin):
model = FlatPage
inlines = [SearchKeywordInline]
admin.site.register(FlatPage, FlatPageAdmin)
When I load the Admin page, I receive:
AlreadyRegistered at /admin/
The model FlatPage is already registered
Exception Value:The model FlatPage is already registered
Thank you!
You have to unregister it first as the app itself ships with an admin.py
admin.site.unregister(FlatPage)
admin.site.register(FlatPage, FlatPageAdmin)