my project directories is:
apps/
goods/
models.py
views.py
base.py
trades/
users/
__init__.py
apps/goods/base.py
from django.views.generic.base import View
from apps.goods.models import Goods
class GoodsListView(View):
def get(self, request):
json_list = []
goods = Goods.objects.all()[:10]
for good in goods:
# json_dict = {}
# json_dict['name'] = good.name
# json_dict['category'] = good.category.name
# json_dict['market_price'] = good.market_price
# json_dict['add_time'] = good.add_time
# json_list.append(json_dict)
from django.forms.models import model_to_dict
for good in goods:
json_dict = model_to_dict(good)
json_list.append(json_dict)
from django.http import HttpResponse
import json
return HttpResponse(json.dumps(json_list), content_type='application/json')
i'm debug base.py not get data, but get the error:
from apps.goods.models import Goods
ModuleNotFoundError: No module named 'apps.goods'; 'apps' is not a package
and, i remove 'apps' in 'apps.goods.models', get the error:
from goods.models import Goods
ModuleNotFoundError: No module named 'goods'
env:
pycharm-2017.2
django-1.11.6
why get the error?
Use just from .models import Goods (look at "." before models - it means the module is from current folder ).Because base.py and models.py are in same folder (same app) so you dont need to specify from which app you want to import models. Just simply include it like this.
But if you want to import models from other apps, you should to make apps to be package.In Goods app folder add __init__.py.
Structure should look like:
apps/
goods/
__init__.py
models.py
views.py
base.py
trades/
users/
__init__.py
Than use from goods.models import Goods or from apps.goods.models import Goods
As in the others' comments, you need to create the init file in the folder that should be considered a package. It's called __init__.py however. You have one of these files in apps, make sure you have it in apps/goods as well.
If you still have the same problem, make sure your configuration in Django is correct, i.e. the folder above apps is loaded
Related
Hello,
For educational purposes, I am building a django app with multiple models and relationships.
According to the official tutorial and many implementations I found online, the database models and serializers as well as views are all defined in single files: "models.py", "serializers.py", and "views.py".
So, the project directory looks as follows:
> my_app
> migrations
> __init__.py
> admin.py
> models.py
> apps.py
> serializers.py
> tests.py
> urls.py
> views.py
Depending on how many models are included in the app, those files may grow to hundreds or even thousands lines of code.
As a result, developing and maintaining the application becomes extremely challenging.
I would like to split these files so that every model (and coresponding serializer and view) will be defined in a separate per-model file. As follows:
> my_app
> migrations
> models
> __init__.py
> model1.py
> model2.py
> model3.py
> model4.py
> serializers
> __init__.py
> model1_serializers.py
> model2_serializers.py
> model3_serializers.py
> model4_serializers.py
> views
> __init__.py
> model1_views.py
> model2_views.py
> model3_views.py
> model4_views.py
> __init__.py
> admin.py
> apps.py
> tests.py
> urls.py
I encountered some difficulties in splitting these files and have not yet found an optimal solution.
The Problem
In order to define a serializer -> corresponding model should be imported.
And in order to define a view -> corresponding model and serializers should be imported.
There are some difficulties importing objects from models/files located in the same level as the parent directoriey.
For example: Importing model to serializers/model1_serializers.py results an error
from models.model1 import Model1 # error: Unresolved reference 'models'
from my_app.models.model1 import Model1 # error: Unresolved reference 'my_app'
What I have tried
Mark project directory as source in pycharm - After marking "my_app" folder as source the following import works. But running the code outside of pycharm (cmd for example) results import errors.
from models.model1 import Model1
Adding the project direcrtory to sys.path - sys.path contains a list of directories that the interpreter will search in for the required module. So adding the following lines should make import possible (in file my_app/views/model1_views.py), but it doesnt work, pycharm still marks the import lines as errors. Do you know where is my mistake?
import os
from sys import path
path.append(os.path.dirname(os.path.dirname(__file__)))
from my_app.models.model1 import Model1
I would very appreciate if you could explain my mistake and propose a solution for spliting those files, thank you!
Don't know if it's advisable to create a new view and serializer file for each model, it kinda makes things messy as the app grows.
If it's just the model you can do what's mentioned in the Django docs
Where you can remove the models.py file and instead create a models directory and have your different model files there as such: myapp/models/, myapp/models/first_model.py etc.
But if you basically want to separate concerns you can create a new Django app for each function/concern, like this:
> my_app_one
> migrations
> __init__.py
> admin.py
> models.py
> apps.py
> serializers.py
> tests.py
> urls.py
> views.py
> my_app_two
> migrations
> __init__.py
> admin.py
> models.py
> apps.py
> serializers.py
> tests.py
> urls.py
> views.py
This should fix your import issue.
Instead of making multiple models, serializers and views files make multiple apps!
That way is more organized and also you can link apps together and import whatever you like from other applications!
You need to add a package __init__.py file in my_app, and import from there:
from my_app import models
models.Model1.objects.all()
This tells Python that my_app is a package, and makes the submodules importable from it.
You thus structure your project as:
my_app/
__init__.py
models/
__init__.py
model1.py
model2.py
...
serializers/
__init__.py
...
views/
__init__.py
...
...
And then import from the my_app package.
Note that often models, serializers and views are grouped per application, not per model. So you make app1, app2, etc. subpackages, and place the models, serializers and views for that app in there.
Say I have a django app where I'm using folders and subfolders to organize my models:
app
models
__init__.py
accounts
user.py
profile.py
social
facebook.py
twitter.py
linkedin.py
admin.py
apps.py
urls.py
views.py
My __init__.py file is as follows:
from .accounts.user import User
from .accounts.profile import Profile
from .social.facebook import Facebook
from .social.twitter import Twitter
from .social.linkedin import LinkedIn
Is there any way to group these imports together or make the code shorter?
E.g. (obviously doesn't work)
from . import *
# or
from .accounts import *
from .social import *
Nope. The package that contains a module will not necessarily know anything about the contents of the module, so in your case accounts doesn't know anything about the User class in accounts.user. There isn't any general way to group things more than what you're already doing.
I am trying to create a custom python script within my Django application. This script requires the use of my app models. I am unable to figure out how to import the models appropriately to be used within this script.
My project directory:
-my_proj(name:ais)
-my_app(name:pages)
-__init__.py
-models.py
-urls.py
...
-utils
-__init__.py
-custom_script.py
So if I wanted to access the pages.models from the custom_script.py how might I do this?
I have attempted various imports such as from django.core.management import settings and from django.core.wsgi import get_wsgi_application but I still get an error stating the following:
ModuleNotFoundError: No module named 'pages'
There is a lot of app configuration done by Django to make your models and settings properly available. The best way to get Django to do this configuration is to make your script a management command, which will be run by python manage.py <your_script_name>. How to make your own management commands is covered by the docs. https://docs.djangoproject.com/en/3.2/howto/custom-management-commands/
I always use runscript for this, which is part of django-extensions. It requires installing this library, but it's well worth it. You can then create a scripts/ directory in your project root, and you'll have all your models available.
Simply
pip install django-extensions
and then follow the steps here
You can write a custom Command:
Add a management/commands directory to your app:
my_app/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
my_command.py
Then you can create the file my_app/management/commands/my_command.py, contains something like below:
from django.core.management.base import BaseCommand, CommandError
from my_ap.models import MyModel
class Command(BaseCommand):
help = 'Command to update some field'
def add_arguments(self, parser):
parser.add_argument('ids', nargs='+', type=int)
def handle(self, *args, **options):
for cur_id in options['ids']:
try:
obj = MyModel.objects.get(pk=my_id)
except MyModel.DoesNotExist:
raise CommandError('MyModel "%s" does not exist' % my_id)
obj.for_index = False
obj.save()
self.stdout.write(self.style.SUCCESS('Successfully closed "%s"' % my_id))
one way to see all of the models in your app is to import apps from django apps and use the get_models method.
from django.apps import apps
then you can use a comprehension in in order to view all of your models and their path. once you see the path you want you can import it at the top of your script.
models = { model.__name__: model for model in apps.get_models() }
input models into your shell to see the list of models in your app and the path from root
Also you make sure that you have import setup in your script
I have a Django project containing some files which are, obviously, not automatically discovered by Django. My workaround is to import them in urls.py so that Django can see them. This is how my urls.py looks like:
from django.contrib import admin
from django.urls import path
from custom_file_1 import * # "unused" import
from custom_file_2 import * # "unused" import
urlpatterns = [
...
]
My IDE considers the commented imports unused, since they are not used, but they are vital so that Django can process those files.
And the question: is there any nice way to let Django see those files? And how to do that?
It is usually not a good idea to import things with wildcards. Imagine that in one of the custom files some object with the name path is present, then it will override the reference to the path function you imported from django.urls.
Usually one imports such files (that for example contain signals, etc.) in the AppConfig.
In the directory of the app, there is an __init__.py file. You can write
# app/__init__.py
default_app_config = 'app.config.CustomAppConfig'
In your app directory, you then define the config of your app:
# app/config.py
from django.apps import AppConfig
class CustomAppConfig(AppConfig):
name = 'app'
def ready(self):
import custom_file_1 # noqa
import custom_file_2 # noqa
Here # noqa is used to ignore the flake8 warnings.
So i'm trying to create an application for user interaction with stream_django. So far everything was going well until I got error:
'User model not registered. Please register model with actstream.registry'.
So after searching for some time, I modified my apps.py to be like this:
The project is called reviews
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "reviews.settings")
os.environ["DJANGO_SETTINGS_MODULE"] = "reviews.settings"
django.setup()
from django.apps import AppConfig
from django.contrib.auth.models import User
class MyappConfig(AppConfig):
name = 'myapp'
def ready(self):
from actstream import registry
registry.register(User,self.get_model('Post'),self.get_model('UserProfile'))
But now I'm getting error:
'AppRegistryNotReady("Apps aren't loaded yet")'
I'm not sure what to do anymore, any help is appreciated.
I faced the same problem but I found that the solution was to add the default_app_config setting in the __init__.py of your main project (same location as your settings.py).
For your case, that __init__.py file should look like this:
# reviews/__init__.py
default_app_config = 'myapp.apps.MyappConfig'