django package organization - python

I plan to build my project in Django framework. However, I noticed that all Django packages have models.py file. Now, let say I have a set of general purpose functions that I share between several apps in the project and I plan to put these functions definitions in a separate package (or app for that matter?). So, should I create an app "general" and copy-paste these functions into the models.py file? Or can I just create a general.py file in the "general" app directory and leave models.py empty? What is the "Django" way to do that?
Thanks.

models.py file is used to define the structure of database. So you should leave it for defining your database entries. You can make an app named generals and put general.py in that app, and from there you can use it by calling it in any app.

I usually create a utils.py file under my main app that is created from the django-admin.py when starting the project.

I plan to put these functions definitions in a separate package (or app for that matter?)
Before you decide to make this an app (and if you do decide to make it an app), I recommend you take a look at James Bennet keynote on Developing reusable apps and hist post on laying out an application. From one of his slides:
Should this be its own application?
Is it orthogonal to whatever else I’m doing?
Will I need similar functionality on other sites?
Yes? Then I should break it out into a separate application.
If you're cramming too much functionality in one single general purpose app, it might be better to split your general purpose app into multiple reusable apps.
Going back to your original question, Django is expecting a models.py file in every app. So you must have the file even if it's empty.
Inside your models.py, you should only have the application’s model classes. So, you wouldn't be following a best practice if you put inside models.py some miscellaneous code you want to reuse.
From the laying out an application post I mentioned before:
At the application level, I usually drop in a few more files depending on exactly what the application is going to be using:
If the application defines any custom manipulators, I put them in a file called forms.py instead of in the views file.
If there are multiple custom managers in the app, I put them in a file called managers.py instead of the models file.
If I’m defining any custom context processors, I put them in a file called context_processors.py.
If I’m setting up any custom dispatcher signals, they go in a file called signals.py.
If the application is setting up any syndication feeds, the feed classes go in a file called feeds.py. Similarly, sitemap classes go in sitemaps.py.
Middleware classes go in a file called middleware.py.
Any miscellaneous code which doesn’t clearly go anywhere else goes in a file or module called utils.
All of this does not answer directly your original question:
can I just create a general.py file in the "general" app directory and leave models.py empty?
But I hope this gives you additional information to make a decision that better fits your project and requirements.

Related

Django: generate python code from command line

Is here a way to write a Django command to generate code automatically?
In my case: every time I create a new model I must create the following stuff too:
Create Administration classes in admin.py
Create service functions related to this model.
Create a factory using FactoryBoy.
Create test classes.
It would be nice if there was a command that generates this stuff automatically. Not everything, of course, but just the basic, the definition.
Is there something like this today in Django? Or is there a way I can write Django commands to generate code?
I have not personally used it yet but you could try to use the third-party package
Django baker Django Baker that offers that functionality
Django Baker wants to help you get your projects up and running
quickly. Given one or more app names, s/he will automatically generate
views, forms, urls, admin, and templates for all of the models in the
models.py file. All files are pep-8 compliant (with exception to the
maximum line length rule, which I don't agree with).
Once you add a single urlpattern to your project's URLconf, you'll
have a working list view, detail view, create view, update view, and
delete view for each model in your app.
Optionally you may specify which models in an app to bake if you'd
rather not generate files for all of them.
Try django commands and jinja2 templates.
With the execution of custom defined command, set of file templates can be updated with appropriate content and copied to respective folders as per need.

Django: how to fully decouple apps when it seems they are coupled? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Note: I am not a proper python programmer... but I use python extensively. I do things like write classes with inheritance, use iterators and comprehension, etc. My point is that I do not have a full grasp of the language, e.g. what exactly constitutes an python object, why __init__.py is needed other than to specify a module, etc. In relation to Django, I have written multi-app sites (with the help of S.O.) and have really enjoyed Django's templating system, blocks, and how they can be nested. Now are my apps fully decoupled and reusable? That this is subject of this post.
I state this disclaimer because a lot of the Django resources seem to assume that one knows these things. This makes understanding some of the documentation and S.O. questions difficult for a person who is just an (subpower)-user. So please answer this question with that in mind.
Question
These questions are inspired by both the question When to create a new app with startapp in django? by #håkan and the answer given by #antti rasinen which links to James Bennett's 2008 PyCon presentation
A few key points from Bennett's presentation are:
sites are a collection of apps
an app does one thing and one thing well
Which directs me to his section "Project coupling kills re-use" that mentions:
Single module directly on Python path (registration, tagging, etc.)
Related modules under a package (ellington.events, ellington.podcasts, etc.)
Question 0
A "module" in this case is just an app made of other apps?
Question 1
(Apps with related functionality and shared models )
What should I do when apps share models?
In Barrett's slides he implies that user registration and user profiles are distinct and should be distinct apps. (He certainly states that profiles have nothing to do with user registration).
So if I wanted both, would my project have two apps like:
user-registration
user-profile
even though the app user-profile will need the user model from user-registration? Or do I make a single app (module):
user-app
registration
profile
which contains both?
Question 2
(Apps with distinct functions but shared models)
Extending the example from question 1, lets say that my main app (or some other app that is used by the main app) utilizes some aspect of the user model (e.g. recently active members if it was a chat site).
Clearly my main app gets this information from the user model. Does my main app now get bundled under the user-app module?
This may not be the best example, but the point is as follows:
I have two apps app-dependency and app-needs-dependency, where each app does its one thing and one thing well... It is just that app-needs-dependency needs information from app-dependency. What do I do in this case, if everything else about app-needs-dependency is completely decoupled from app-dependency (so it could be used in other projects)?
Question 3
(writing apps for flexibility)
Now I have my site with its couple of apps. Each app does its one thing and does it well. The main app serves as the landing page/ overview in this case.
I want all my other apps to use / inherit the static and template files of the main app.
Where do I store all the static files and templates? In the main app and set that as the default for the other apps? Or where should these static files / templates (e.g. base.css, base.html) go?
Do I make a copy of these files for each other app, so they can be run even though this is redundant?
Which makes my app more flexible?
Question 0
A "module" in the Python context is simply a file that contains definitions and statements. So "related modules under a package" really just means "split your code into separate files based on what the code is doing".
Describing it as "an app made of other apps" is to start confusing Django's concept of an app with Python's concept of a module (which, as stated above is just a file that houses some code).
Question 1
What should I do when apps share models?
You should still try and stick to the "apps do one thing and do it well" maxim. In this case separate profile and registration apps seems like a good idea - because they have quite different functions. A registration app is going to contain the logic for allowing users to register on your site. A profile app is all about what information you will store about a user.
There is nothing wrong with these two apps having a relationship to each other - see below.
Question 2
Let's say that my main app (or some other app that is used by the main app) utilizes some aspect of the user model (e.g. recently active members if it was a chat site). Clearly my main app gets this information from the user model. Does my main app now get bundled under the user-app?
No. It should still be a separate app, with links to the other app.
The user model is actually a good example. Django allows you to specify a custom user model that lets you store whatever additional data you want about a user.
Now, there are loads of third party apps out there that do things like registration, authentication, etc for users. They are designed to work with any user model, not just Django's default one. The way they do that is to use get_user_model() wherever they need to reference the User model, instead of directly importing django.contrib.auth.models.User.
This means that you can use those third party apps with whatever user model you have defined for your own project.
Django's get_user_model() utility is there to serve a very common use case. However the same principle can be extended to your own apps. If there is a dependency between your apps that you think should be swappable, then you can provide a way to swap it out - e.g., a setting/configuration that allows any other project using your app to specify an alternative.
There are hundreds of examples of this kind of configurability in the Django ecosystem. For example, Django itself ships with its own django.contrib.auth authentication app. However if you want to implement your own authentication logic, you don't have to reimplement the entire auth app again yourself (that would be a huge pain). Instead you specify an an authentication backend that it's auth app will use to authenticate. The auth app is designed to allow any project to swap out a core piece of its functionality with minimal effort.
So in your main app, you might define a setting that controls which profile model to use. This means that if someone else wants to use a different profile model, they simply change this setting and they're all set. They are no longer tied to your profile app.
For example - let's say you have a main app that has a view that displays some user data, but also provides a link to a registration view that is provided by a different app. You want anyone else to be able to use that app regardless of what registration app they are using. So you can make this view resuable like so:
In main/views.py:
from django.contrib.auth import get_user_model
from django.conf import settings
from django.urls import reverse
class UserDetailView(DetailView):
# First of all, we're using get_user_model so that a project
# can specify whatever user model it wants, and still use this
# view.
model = get_user_model()
def get_context_data(self, *args, *kwargs):
ctx = super().get_context_data(*args, **kwargs)
# We want to add a link to a registration view into this template context.
# But we want this to be configurable.
# Your REGISTRATION_URL would be something like 'profile:registration'
ctx['registration_link'] = reverse(settings.REGISTRATION_URL)
return ctx
Question 3
The main app serves as the landing page/ overview in this case. I want all my other apps to use / inherit the static and template files of the main app. Where do I store all the static files and templates?
You should store the templates in each respective app. If your main app is providing the base templates, then those should reside in the main app.
If your profile app is then providing a registration view, then the template for that should live in the profile app. There is nothing wrong with it extending the base template from the main app - this can easily be overridden by a project that wants to.
It's fine to make assumptions about how two apps are related to each other - as long as you're careful to allow overriding of those assumptions.
I have to admit your question is not a technical one but rather a conceptual and dogmatic one.
No answer is absolute and universally valid and every detail about how you project is structured and should behave can change the perspective.
As you wrote, each Django app does one thing and it does it well.
I would extend that to the point that each app should contain no more than one Model and at most, it's closets dependents.
Ex: the Product with it's Category, Color, Image
"What Changes together, stay together"
You will have plenty of logic to cover inside that app with only these ones.
Try to look at Django framework as a tool to create your project..this is the final goal...but if you want also to create reusable apps try to create them as independent as possible, or at least dependent to some Django features:
ex: a reusable app and totally independent would be an app that only requires User Model, Sessions, Groups included in Django. You get the idea of dependent but still autonomous app.
An app is part of a project after all...either here or in other part after you build it. Look at it as if it would be a simple function...can run alone or can depend on other functions result...at what point you keep everything inside one function and when you decide to split them in 2 separate ones.
So:
Question 0:
An app is the smallest piece that can run by it's own...having models, views, templates, urls, static files.
It can depend also on other apps...so answer is YES
Question 1:
Always keep things separate by functionality...
User Auth is dealing with user creation and their authentication
User Profile is dealing with personal data of the User
Question 2:
Nothing gets bundled. Everything stays at the same level as 2 different but dependents apps
Question 3:
You can do as you wish.
You can do static as a central place and templates specific for each app or everything central.
No right answer here but only what scales well for your project.
This is a great question and it covers all the questions associated to structuring the project I asked myself when i started working with Django.
Question 0:
Yes, in that case, a module is an app which consists of serveral apps (ellington.events, ellington.podcasts).
Question 1, Question 2, Question 3:
Django is a general purpose, full stack web framework. Since it is general purpose, a lot of it depends on your particular use case. You need not have an entire Django project follow a particular structure (if you want to achieve code reuse AND functional decoupling AND relational decoupling).
With that said, if you can prioritize what you want to achieve, you can go with one pattern over the other.
Let's take the example of Blog.
Code Reuse:
For achieving maximum code reuse, you have to identify what parts of your project is worthy of reuse. Once you have done that, you can set your project structure accordingly.
Project Structure:
BlogProject
-CommonApps
--AbstractUser(abstract class (just like it's java counterpart) )
--AbstractActivity
--AbstractComment
--AbstractArticle
-ProjectApps
--BlogUser (extends AbstractUser)
--BlogActivity (extends AbstractActivity)
--BlogComment (extends AbstractComment)
--BlogArticle (extends AbstractArticle)
The functionalities that can be shared across multiple projects should be implemented in abstract apps, and the ones specific to project can be implemented in Project apps.
Relational Decoupling:
You can create apps to represent the relations between two other apps, and implement all the functionality involving two different apps in that relation.
Project Structure:
BlogProject
-User
-UserActivityRelation
-Activity
-Article
-ArticleCommentRelation
-Comment
-UserCommentRelation
-and so on
Functional Decoupling:
This is the most common practice - create apps for particular functionality.
Project Structure:
BlogProject
-Article
-Activity
-User
-Comment
The point I am trying to make here is that the choice is yours. In more complex projects, it won't be so white and black.
You, depending on what an "app" means to you, and what you want it to do in a particular project and other projects, can decide on a particular structure.
Django keeps it abstract to give you the ability to do that.
I always go for an app setup that makes sense to that particular project. In a project not all apps are reusable. And having flexible/reusable apps does not make sense in all the cases.
As a general rule of thumb, Django devs say an App should be something whose functionality can be described with one sentence. But Django is designed so that you can bend the rules for your projects if you have to.
DISCLAIMER: Functional decoupling and relational decoupling aren't textbook terms. I just used them to describe what I meant here.

Using Python Objects in Django Applications

I apologize if this seems like a stupid question but I'm still very much a novice Python/Django programmer. Is it normal to create Python objects in a Django application that aren't models that will be saved in the database?
I'm creating what's become a fairly large Django application and, to me, my code is really starting to "smell". What I mean is that my views are becoming very large because I'm taking a procedural rather than object-oriented approach. My intuition tells me that my code might be simpler, easier to test, and more robust in the long run if I were using more objects with their own attributes and behaviors rather than passing information from one function to the next in my views.
What's hanging me up is that these aren't objects I want to save in my database so I don't quite know if I should be using them and, if I should, where I'd put them. Is the approach I'm proposing typical in a Django application? If so, where would I store those objects with respect to the Django model/view/template structure? Also, are there any popular Django modules or libraries that do what I'm describing that I should study?
Thanks in advance for your response.
You can store your objects anywhere. There could be helper functions in your views file or models file or wherever. I prefer to put miscellaneous functions in a utils.py file but that is not a convention, just something I end up doing. I end up putting most of miscellaneous helper functions and base classes in a common app, and more specifically a common.utils file.
In one project I have lots of apps, and each app has an api client. The base class for the client resides in an app called common. Then each app then has their specific client in client.py file
project
common
client
app1
client
app2
client
Then in app1 client
from project.common.client import BaseClient
class ConcreteApp1Client(BaseClient):
pass
Then in my views or management commands or models or wherever the concrete client can be imported and used as normal. from project.app1.client import ConcreteApp1Client
Django also has class-based views if you feel certain variables could best be encapsulated in a class.
https://docs.djangoproject.com/en/dev/topics/class-based-views/

django app organization

I have been reading some django tutorial and it seems like all the view functions have to go in a file called "views.py" and all the models go in "models.py". I fear that I might end up with a lot of view functions in my view.py file and the same is the case with models.py.
Is my understanding of django apps correct?
Django apps lets us separate common functionality into different apps and keep the file size of views and models to a minimum? For example: My project can contain an app for recipes (create, update, view, and search) and a friend app, the comments app, and so on.
Can I still move some of my view functions to a different file? So I only have the CRUD in one single file?
First, large files are pretty common in python. Python is not java, which has one class per file, rather one module per file.
Next, views, even as the standard used, is a python module. A module need not be a single file. It can be a directory containing many files, and __init__.py
And then, views.py is only a convention. You, the application programmer are referring to it, and django itself doesn't refer anywhere. So, you are free to put it in as many files and refer appropriate functions to be handed over, the request to, in the urls.py
They don't have to go in views.py. They have to be referenced there.
views.py can include other files. So, if you feel the need, you can create other files in one app that contain your view functions and just include them in views.py.
The same applies to models.py.
Django apps lets us separate common
functionality into different apps and
keep the file size of views and models
to a minimum? For example: My project
can contain an app for recipes
(create, update, view, and search) and
a friend app, the comments app, and so
on.
I don't know about the "to a minimum" part - some apps are just big in views, others big in models. You should strive to partition things well, but sometimes there is just a lot of code. But other than that, this is a fair summary of Django apps, yes.
I also very much dislike long files.
Of course what you read in the other answers is true, but I exploit some very nifty python equivalence:
views.py
and
views/__init__.py
are pretty much functionally equal - by that I mean that if the both contain def my_view() then
from views import my_view
will work the same in both cases!
From there it's easy to structure your long files into smaller ones, yet keeping the naming convention that every django developer is used to:
views/__init__.py
views/largemodel_view.py
then in __init__.py don't forget to import the views from largemodel_view.py.
With large applications I do the same with models though you must remember to set the Meta.app_name:
class MyModel(models.Model):
...
class Meta:
app_name = 'yourappname'
because django will not pick it up magically otherwise for the Admin (but it will still load it, thanks to Python!)
so my apps usually end up looking something like:
project/settings/__init__.py
/..othersettings..
/app_1/models/__init__.py
/...
/views/__init__.py
/...
/templates/
/static/
urls.py
/urls.py
etc.
though of course there's no limit (urls could be split too, etc.etc.)

Django: Where to put helper functions?

I have a couple of functions that I wrote that I need to use in my django app. Where would I put the file with them and how would I make them callable within my views?
I usually put such app specific helper function in file utils.py and use someting like this
from myapp.utils import my_cool_func
def view_coolness(request):
data = my_cool_func(request)
return render_to_response("xxx.html")
but it depends what you helper does, may be they modify request , the could be part of middleware, so you need to tell what exactly those helper functions do
create a reusable app that include your generic functions so you can share between projects.
use for example a git repo to store this app and manage deployments and evolution (submodule)
use a public git repo so you can share with the community :)
If they are related to a specific app, I usually just put them in the related app folder and name the file, 'functions.py'.
If they're not specific to an app, I make a commons app for components (tests, models, functions, etc) that are shared across apps.
I am using new python file service.py in app folder. The file contains mostly helper queries for specific app. Also I used to create a folder inside Django application that contains global helper functions and constants.

Categories