Sharing Django user model between two apps in the same project - django

I see some similar questions, but they don't appear to be the same or have answers.
I am practicing with Django and trying to make a simple dutch auction project. Initially I thought that the idea would be to create two distinct apps, a buyer app and a seller app, and just have them share databases (or three apps, a commonApp a buyerApp and a sellerApp). However, the more I dig into this the more complicated it seems - I feel like Django isn't really meant to have different apps that are designed around sharing all of their data from one set of tables (maybe I'm wrong?), loosely based on what I've found about having to modify the way Migrations work to accommodate this.
So idea #2, just make one app that separates out the functionality by carefully managing the views, but keeping just one set of models since pretty much all of the data I can think of (the users, the products, etc.) are shared anyway. This seems like it has the advantage of letting Django do all of the data management without my having to sweat about the database design. However, I worry that maybe managing the views will get to be overly complicated.
Maybe there is an idea #3 that makes sense for this sort of project, one that I haven't considered because I am a newb, maybe one that tells me that Django isn't even the right tool for this job...
I tried programming idea #1 and it quickly became spaghetti and only worked when things were very small. I am currently working on idea #2 and so far I think it's going OK, but I'm having trouble conceptualizing how to separate stuff in views, but this could very well just be my lack of experience.
So my question is: is there an obvious resource for this sort of information that I'm missing? If so, could you please point me that way?

Inside your Django project:
manage.py startapp sellers
manage.py startapp buyers
manage.py startapp common
Add these three apps to settings.py. Depending on your Django's version it can be just 'sellers', 'buyers', 'common' or 'seller.apps.SellerConfig' and so on.
Write your models in common/models.py, and any other logic related to both apps.
Then, in your seller or buyers views:
from common.models import * # or a particular model
Hope this helps.

Related

Should I use an internal API in a django project to communicate between apps?

I'm building/managing a django project, with multiple apps inside of it. One stores survey data, and another stores classifiers, that are used to add features to the survey data. For example, Is this survey answer sad? 0/1. This feature will get stored along with the survey data.
We're trying to decide how and where in the app to actually perform this featurization, and I'm being recommended a number of approaches that don't make ANY sense to me, but I'm also not very familiar with django, or more-than-hobby-scale web development, so I wanted to get another opinion.
The data app obviously needs access to the classifiers app, to be able to run the classifiers on the data, and then reinsert the featurized data, but how to get access to the classifiers has become contentious. The obvious approach, to me, is to just import them directly, a la
# from inside the Survey App
from ClassifierModels import Classifier
cls = Classifier.where(name='Sad').first() # or whatever, I'm used to flask
data = Survey.where(question='How do you feel?').first()
labels = cls(data.responses)
# etc.
However, one of my engineers is saying that this is bad practice, because apps should not import one another's models. And that instead, these two should only communicate via internal APIs, i.e. posting all the data to
http://our_website.com/classifiers/sad
and getting it back that way.
So, what feels to me like the most pressing question: Why in god's name would anybody do it this way? It seems to me like strictly more code (building and handling requests), strictly less intuitive code, that's more to build, harder to work with, and bafflingly indirect, like mailing a letter to your own house rather than talking to the person who lives there, with you.
But perhaps in easier to answer chunks,
1) Is there REALLY anything the matter with the first, direct, import-other-apps-models approach? (The only answers I've found say 'No!,' but again, this is being pushed by my dev, who does have more industrial experience, so I want to be certain.)
2) What is the actual benefit of doing it via internal API's? (I've asked of course, but only get what feel like theoretical answers, that don't address the concrete concerns, of more and more complicated code for no obvious benefit.)
3) How much do the size of our app, and team, factor into which decision is best? We have about 1.75 developers, and only, even if we're VERY ambitious, FOUR users. (This app is being used internally, to support a consulting business.) So to me, any questions of Best Practices etc. have to factor in that we have tiny teams on both sides, and need something stable, functional, and lean, not something that handles big loads, or is externally secure, or fast, or easily worked on by big teams, etc.
4) What IS the best approach, if NEITHER of these is right?
It's simply not true that apps should not import other apps' models. For a trivial refutation, think about the apps in django.contrib which contain models such as User and ContentType, which are meant to be imported and used by other apps.
That's not to say there aren't good use cases for an internal API. I'm in the planning process of building one myself. But they're really only appropriate if you intend to split the apps up some day into separate services. An internal API on its own doesn't make much sense if you're not in a service-based architecture.
I cant see any reason why you should not import an app model from another one. Django itself uses several applications and theirs models internally (like auth and admin). Reading the applications section of documentation we can see that the framework has all the tools to manage multiple applications and their models inside a project.
However it seems quite obvious to me that it would make your code really messy and low-performance to send requests to your applications API.
Without context it's hard to understand why your engineer considers this a bad practice. He was maybe referring to database isolation (thus, see "Working multiple databases" in documentation) or proper code isolation for testing.
It is right to think about decoupling your apps. But I do not think that internal REST API is a good way.
Neither direct import of models, calling queries and updates in another app is a good approach. Every time you use model from another app, you should be careful. I suggest you to try to separate communication between apps to the simple service layer. Than you Survey app do not have to know models structure of Classifier app::
# from inside the Survey App
from ClassifierModels.services import get_classifier_cls
cls = get_classifier_cls('Sad')
data = Survey.where(question='How do you feel?').first()
labels = cls(data.responses)
# etc.
For more information, you should read this thread Separation of business logic and data access in django
In more general, you should create smaller testable components. Nowadays I am interested in "functional core and imperative shell" paradigm. Try Gary Bernhardt lectures https://gist.github.com/kbilsted/abdc017858cad68c3e7926b03646554e

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.

Is splitting a large django app a good practice?

I have created a complex E-R diagram for a django site I'm developing. It maps to 11 tables in the database. The site has many features, so I would like to split it into multiple apps. The Django manual said that Django apps should be pluggable, but if I split the models into many apps, they would be dependant on each other. Is this a good practice? If not, how should I structure my application?
Thanks
I wouldn't worry over the statement about making apps pluggable. Sure, if it could be a useful app in other projects, you may want to - but nothing enforces this.
There is no harm in making internal apps dependent.
Personally, my project-specific apps live inside the project module (or for larger projects, inside a project.apps module). This way, you're not polluting the python import namespace with your one-time apps.
You could separate them out into self contained apps, and they would work within the context of your project.
You could also create each app so it's totally independent. This often takes a bit more work, a nice example of this is Django-tagging, which you can basically attach to any other object.
So yes, you can do it. However if the app is just for you it may not be worth the effort (IMHO) ;)