How to decide how to split up your Django project into apps - django

I have a project that I wrote in PHP/symfony that uses 45 tables. I'm in the process of porting it to Python/Django.
There's a belief I've held for years that you should split up your projects into a bunch of small files rather than a few huge files. From what I understand, that's not an odd thing to believe. In Rails and symfony, there's a one-model-per-file convention. In Django, however, it seems that most developers put all of each app's models in one file.
This makes sense to me if your apps are each small enough. It doesn't make sense to me for large apps, though, and what I have is at least one large app.
Out of the 45 tables my project uses, 35 are closely related. I have a script that imports data from CSV files. For each line in each CSV file, I save 50-80 pieces of data into 30-35 different tables in one fell swoop.
Maybe I'm just thinking about this the wrong way but it would seem incredibly odd to me to divide my project into 6 or 7 different apps when almost all my tables are inextricably linked. When I touch one table, I touch all 35 tables. The delineations would have to be arbitrary. What would be the point of that?
Please forgive me if I come off as biased because I certainly am biased. I'm not having this problem in symfony and I wouldn't be having it in Rails. (I chose Django because of GeoDjango and Python's GIS capabilities.)
In a perfect world, I would have one model per file.
If I try to have one model per file, I get circular reference problems.
I could avoid the circular reference problems by putting all my models in one file but that feels wrong to me.
I could avoid putting all my models in the same file by splitting them into separate apps, but in order to end up with sufficiently small apps, I'd have to break up my project in arbitrary (and therefore pointless) ways.
What should I do?

If having one model per file would be the perfect answer for you, there's an app for that.
I've never done it on a scale of 80 model files but I can certainly point you towards another stack question:
About 20 models in 1 django app
http://djangosnippets.org/snippets/1838/
What kind of circular reference problems are you having by the way? If it's with ForeignKey definitions, here's a way around that...
http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey
You can also look into django.db.loading.get_model, but some may frown on this.

Related

Split big apps in django

I've an app which is growing pretty big, doing too much thing as a single app, so I'd like to split it in 2 or 3 "sub-apps"
The problem is that there are a dozen of models which are linked to each other (foreing key, manytomanyfields, etc.)
I've read LOTS of times that apps should be self-consistent, so, are there any best practices to split a big app in several ones linked to each other?
--> how bad is importing models from other apps?
I didn't hear about a best practice solution, but here's what I would usually do, and I split apps a lot:
Step 0 - When is an app "too big"?:
An app should be an (independent) logical unit. Independent is actually misleading, of course you can have dependencies like django.conrib.auth, what you should have tho are cross dependencies. They will eventually lead to looping imports. That being said, you app can grow quite large, with is totally fine.
If you having problems organizing your code, I may remind you of the fact that every module can be build as a package. You simply split your models.py into models/__init__.py and models/LOGICAL_UNITS.py.
The only reason why you should split an app is because you can, not because you want to ;)
Step 1 - Overview
Use django_extensions' graph printing capabilities.
This should give you a good overview an might help you to find so called "communities". Groups of models that have strong cross dependencies.
Those communities usually make a pretty good app.
Step 2 - Naming:
If you cant find a name for you're new application, it probably isn't one.

How independent should Django apps be from one another?

I'm having trouble determining how I should split up the functions of my project into different apps.
Simple example: We have members, and members can have one more more services. Services can be upgraded, downgraded, other services added on, and can also be cancelled. (This is extremely simplfied, were it that simple in reality I'd use a pre-made solution)
My first thought was to make this into a 'member' application, and then a 'services' app that takes care of renewals, up/downgrades and cancellations.
I then thought I should probably make a renewal app, an up/downgrade app, and a cancellation app. But, these apps would all depend on the same table(s) in the DB (members and services). I thought applications were supposed to be independent from one another. Is it ok to make applications that are heavily dependent on other apps models?
Along the same lines, which application should I use to store the models to create the services table if so many apps use it?
I think you first thought was right: you don't get so many benefits of splitting everythin into multiple apps, and on the contrary it could become messy and hard to mantain.
The Django way of doing things depends a lot of the models. Each object is mapped to an entity on the data model. Your apps are mostly organised in relation to such data model. So, if you have an entity (service) that has different pieces, it is better to understand such pieces as parts of the same thing. The other entity (member) should be another one since it is a different thing.
There is no penalty of importing models from different apps. The most important thing is anyway building data model to be consistent.
The point of apps is to allow code which is intended to be reused as an addon by third parties. You probably won't want to split your projects up much, if at all into apps.

Could Django project directory more simple structure with or without South?

I'm a new comer to Django.
However, I'm little confused on directory structure of Django. For instance I have to write so many models.py in different place, which, presumably, will cause difficulty to maintain the project in future. I want to make it more like real MVC structure, with every model files in a models directory.
Could it be possible to do that with using South, which seems to only looking at models.py, or should I consider different migration tools?
Django organizes code into 'apps', which is why you have separate models.py files, and I don't think there's a way to put them all in one directory instead, since each app gets its own Python package.
However, the way I normally structure my code, is to have one (or a few, if it's a larger project) app for all my code, since you can have as many Models in a single models.py file as you want.
I don't think South will help you with that, but it will make it a lot easier to manage your migrations, so I would highly recommend it.
I dont think there is a provision in django to put all models at one place. and also it is bad idea to put all at one place. because each app has its own DB Schema and putting apps independent is necessary to fulfill reusability factor. Its better to keep the models isolated from each other, attached to their app as it helps reausability.
South does not fulfill this. it just keeps track of ur Db migrations n fixtures.
At one point or the other, South comes into picture, no matter how perfectly the DB Schema is designed.

better architecture in django is different apps. or single App for different components?

I have intended to have an app. where I want to have different things having relations with each other and want to know that whether I should have them as just different models or as differnt apps. Obviously if this is student, teacher in LMS then they are necessary component of LMS while if this is Job, Professional and Company then there can be different things associated with a job , a professional can have his full profile with different features, company can have different directory listing e.t.c. like features.
So Company and professionals who are users also should be as diff. apps. and job as different app.? Will this way be fine? as Jobs app. don't always everywhere need to have professional data or employer all data other than just name. So it seems like it is more convenient to have them as diff. apps, so that it can be used somewhere else.So is that right way?
Or
As I also want this project to be flexible so will the above make it more complex? And should I just treat them as diff. models instead of diff. apps. as Company and Professional are users , for which django gives Profile features also. So is this right way?
Which way is better one?
thanks in advance.
There is no exact answer here, so it's my opinion.
It is always good to have several apps rather than one big app. Reasons:
apps becomes smaller and it's easier to maintain small pieces of code;
project structure becomes more clear, I just need to look at the file manager to see main parts of the project;
interaction between apps become explicit: easy to test and prevent unnecessary coupling.
Not every Django app should be pluggable. It's ok to have two apps that depend on each other (if you aren't going to distribute them seperately). It's like having two dependent functions: nothing is wrong with it.

Django best practice: number of model classes per file / directory structure

Another best-practice question to those with experience: How many models do you put in one file?
I've seen many examples that stuff all model classes into a single "models.py" file, which really feels wrong to me. In previous projects using other stacks I've gone with one file per model class. How is it done properly in Django for non-trivial applications with, say, 20 model classes? What would the directory structure look like?
Many people, especially those coming from the Rails world, get hung up on the term "application" and start throwing absolutely everything into a single app. In Django, an application is a single-use module that does one thing and does it well. Each application should be describable in one or two short sentences. A "project" is a collection of applications unified by a settings file. Even for something as complicated as an online store , something I'm discovering now, having more than four or five models in a single application is a warning sign: It was better that the store application (which has the shopping cart) be dependent upon upon the product application than have both in the same app. The same was true of invoices and payments, and so on.
Take a look at Django in the Real World, Jacob Kaplan-Moss's presentation about how to write Django applications.
A Django application is encapsulation: it describes one simple object (or collection of objects) and its API. Having 20 models sounds like you don't have a clean API, and therefore a clear concept, of what this app does.
The answer you want is "it depends on what your application does." To that end, what the Hell does an application with 20 models do, anyway? Grab your copy of Refactoring and have fun.