django app file structure - django

Below is a common app file structure:
app/
views.py
forms.py
urls.py
tests.py
I found it's getting hard to maintain the code once the code base is getting big. I am thinking to organize the code based on individual web page, so each web page will have its own view.py, form.py and test.py.
app/
views/
page1_view.py
page2_view.py
forms/
page1_form.py
page2_form.py
tests/
page1_test.py
page2_test.py
Is there any big issue I will run into?

No. Django understands packages and files.
Example if you use
app/
views/
page1_view.py
page2_view.py
__init__.py
you can reference the views as app.views.page1_views without any issues.

The short answer is no. In fact, I've often split views, tasks, and tests as you are doing.

Related

Proper directory structure for app versioning (Django)

I am currently starting work on a existing Django Project, and I need to make changes to the existing APIs. However, I can't change the existing code since old apps and sites have been using it, which might take a lot of time to change the structure, and might break current dependencies for those. So, for now, as asked, I need to maintain separate directories to change/review the existing code and achieve a versioning-like structure for Django apps. What might be the best way/structure to achieve this?
The current structure is simple as given by django-admin startproject
project_dir
|___project_name_dir
|___settings.py
...
|___app_1_dir
|___ __init__.py
|___ views.py, serializers.py
...
|___app_2_dir
...
So, I need to like create versioning type structure for app_1 here. What might be the best approach to do that?
You can create a new app, called api_v2.
But generally i put all applications inside an application folder in the project_name_dir:
project_dir
|___project_name_dir
|___settings.py
|___applications
|___api
|___ __init__.py
|___ views.py, serializers.py
|___api_v2
|___ __init__.py
|___ views.py, serializers.py
|___other_apps
|___ __init__.py
|___ views.py, serializers.py

Is possible to customize the models package path in Django

The default folder structure of a project in Django is something like:
myproject/
- myapp/
- models.py
- myproject/
- settings.p
Would it be possible to change that structure?
I'd like to do something like:
myproject/
- myapp/
- infrastructure/
- models.py
- myproject/
- settings.py
or
myproject/
- myapp/
- infrastructure/
- models/
- __init__.py
- some_model.py
- myproject/
- settings.py
I know I can make a models package and split the models into different files. But I'm looking to change also the name/path of that package.
Yes and no. In that case, your app will be myapp.infrastructure and it will need to be added to INSTALLED_APPS in settings.
Having models.py file and models/ folder is mostly same for python. In this case, you will need to import different models in the __init__.py file inside the models/ folder.
The idea is that somehow your models and other codes should be imported somewhere in the project for django management command to see them (ex: for preparing database migrations - makemigrations command). So as long as makemigrations can see your model, you can place them anywhere. It is just a python's way, not directly related to django framework.
As for the name of basic things (models, views, apps, signals, admin and etc.) - I think the only one required to be in its name is models. As it is used directly by its name in ORM. Check this: Django Applications Documentation
So, it is possible thanks to python's syntax, but it is not recommended by django. Django's design practices were created to make it easier for everyone to write a readable app where you can easily understand where things supposed to be and work easily without learning internal rules of the project that someone else designed. It is very important for project where there are many developers and new members can join any time after the project's start. So, unless you are well aware what you are doing, you are free to develop any custom design you want - after all, all you need is for python to be able to import your functions and classes in other parts of the project.

Are there conventions for naming Django project, setting and main app folders?

My Django site currently looks like this:
my_store/ (project folder)
app_1/
__init.py__
admin.py
apps.py
...
app_2/
__init.py__
...
my_store/ (settings folder)
settings.py
urls.py
...
store/ (main app folder)
__init.py__
...
Where:
my_store is the name of my project
app_1 and app_2 are potentially reusable apps
store contains project-specific logic and configuration (likely not reusable)
Are there established conventions for giving distinct names to each of:
the project folder (my_store)
the settings folder (my_store)
the main app folder (store) -- I've seen a few examples of calling this "main"
De facto / popular conventions welcome, but documented / authoritative conventions preferred.
I like to follow the example of doordash who kindly published a blog post on operating django at scale.
https://blog.doordash.com/tips-for-building-high-quality-django-apps-at-scale-a5a25917b2b5
I think that it answers you specific question succinctly below, but also as some other tips.
The Django tutorial recommends a structure below:
mysite/
mysite/
__init__.py
polls/
__init__.py
But doordash recommends a different structure:
mysite/
mysite/
__init__.py
polls/
__init__.py
I hope that this helps and has some additional details to help clarify.

PyCharm cannot resolve reference in __init__.py with Django project apps

I am at my wits end with this issue, and would love some help resolving this.
I have a Django project with a bunch of sub apps as such:
my_project/
manage.py
my_project/
settings.py
urls.py
wsgi.py
app_root/
__init__.py
app1/
__init__.py
models.py
views.py
urls.py
templates/
[various templates].html
app2/
__init__.py
models.py
[etc]
app3/
[etc]
in my django settings.py i have installed apps as such:
app_root.app1,
app_root.app2,
In PyCharm, I've tried various things but essentially have Content Root as the top "my_project/" and app_root, app1, app2, etc as Source Roots. I've tried just having app_root as the only Source Root, and I've tried having only app1, app2, etc only as Source Roots, but nothing makes any difference.
Everything functions fine. app runs and everything. However, PyCharm has an inability to resolve my apps.
However, if i try this:
import app_root
...
def some_function(self):
app_root.app1.models.My_Model.objects.all()
it will highlight app1 with the error "Cannot find reference 'app1' in '__init__.py'"
This also means it can't do autocomplete anywhere in the path while doing app_root.app1. - it has no idea about models, views, etc. despite having an (empty) __init__.py in every directory.
I also cannot use any refactoring because it always says "Function is not under the source root"
I've spent countless hours trying to get PyCharm to behave but simply cannot find a way to do it. Is there any way this can be done so PyCharm will autocomplete my apps and not keep giving inspection warnings?
I had some similar issues. My solution; within the PyCharm preferences I added a path to app_root in my active Python Interpreter.
After an exchange with the PyCharm folks, here is what I learned:
Django imports all apps in INSTALLED_APPS variable and their models using __import__ for its own purposes.
In your case, it runs
__import__("app_root.app1")
__import__("app_root.app1.models")
After that, you call import app_root and obtain module app_root with app_root.app1 and app_root.app1.models already imported by internal Django code
Fact that Django imports apps and models is Django internals, it is undocumented and may be changed in future releases. We believe you should not rely on it in your production code, nor PyCharm should.
Here is example in bare python (no django):
__import__("encodings.ascii")
import encodings
print (encodings.ascii.Codec) # this code works, but PyCharm marks "ascii" as "unknown module"
So basically, it's not supposed to work as import app_root, but Django funkiness is masking that.

Django 1.4 project wide code ( template tags)

With 1.4 round the corner I thought I would give it a go but I have a question about the new project layout.
manage.py
myapp/
__init__.py
models.py
mysite/
__init__.py
settings.py
urls.py
I can see the logic here and I am a fan of the new layout however if I am having issues with adding project wide code.
For example:
I have created a new templatetag that is specific to this project and doesn't fit logically fit in any one of my apps. To me this should then fit within mysite however (as far as I can tell) this is not then processed. apptag.py (see below) is available but sitetag.py is not. Now, I am assuming this is because mysite not processed in the same way as an app(?).
manage.py
myapp/
templatetags
__init__.py
apptag.py
__init__.py
models.py
mysite/
templatetags
__init__.py
site.py
__init__.py
settings.py
urls.py
My question then is what is the right way to go about this issue? Should I create an app called 'core', 'mysitecore' or such like? I can add 'mysite' to INSTALLED_APPS but that just feels down right wrong. Or is there another option that I am missing here.
Thanks in advance.
Templatetags need to be inside an app that is included in INSTALLED_APPS. This is, in my opinion, a wart in Django that isn't fixed by the new layout. Your idea of using a core app - or, as I often do, utils - is the right one.