Referencing multiple Django projects from a single monorepo - python

I want to be able to write shared functions that can be accessed in one-off batch scripts and also by the running Django service (to use the ORM)
Currently, I have this in the _init__.py under the my_proj module.
if 'DJANGO_SETTINGS_MODULE' not in os.environ:
os.environ['DJANGO_SETTINGS_MODULE'] = 'my_proj.blah.blah.settings'
import django
django.setup()
This works fine for one django project. However, now I want to do reference the ORM functions from another django project, "other_proj" in the same repo from an independent script that lives outside both django projects.
Is there a way to "django.setup()" multiple projects at once?
Or, at least, a way to easily toggle the setup between the two projects?
Or is there a better way altogether? (I realize I could create a client library to hit the services while they are running, but would prefer to remove that overhead)

If you want a Django project to access functionality that resides in a different Django project, a client library is an option (as you noted). You could also consider packaging those sets of functionality as re-usable Django apps that you import into each project, or you could abstract them further into re-usable Python modules which get imported into each project. If you're hoping to use the Django ORM from one Project to access data from a different project, then you might be looking for this SO question: How to make two django projects share the same database
I think with more specifics in your question (such as, for example, function X in Project A you wish you could call from Project B) we might be able to be more specific with guidance.

I'm not sure I quite understand the case you're trying to implement here; two things that sound maybe-sort-of like what you're asking for are:
1) Running Django projects under uWSGI in Emperor mode allows you to serve multiple Django projects from one server simultaneously.
2) Django can be configured to run the same project under multiple domains simultaneously using the Sites framework.
I agree, though, that more detail about what you have and what you're trying to accomplish with it is probably necessary to give a satisfying answer.

Related

Django Server inside another program

I wrote a Django app that collects data from clients and displays them in it's web app.
Now I want to write a script/program (WPF or a small Java App) that manages the Django server. Things like Start/Stop, update Django files, migrate Data etc.
Reason is: I want to stuff all of that into an .exe, maybe with a setup and licensing for my potential customers.
What would be the most professional attempt to do this? I wrote smaller scripts before and built them with pyInstaller, which does not seem to work with Django. Or should I just install a python interpreter with my setup and just run the python files? Then my code would be visible to my customers.
Any tips are appreciated.
you have two options really. either run the app on the customer's hardware or your own. if you don't want your code exposed you should consider hosting the application yourself and providing them with authentication
Django authentication is actually pretty robust, check out these two articles from the official docs. This is a general tutoria on authentication l: docs.djangoproject.com/en/2.0/topics/auth/customizing/… and this is a broader scope one on django in general docs.djangoproject.com/en/2.0/intro/tutorial01
Edit: just do it here

how to handle common code in a django project which is used by multiple apps

diving deeper into django I came across the challenge to handle code which is not specific to 1 app but is shared/used by multiple apps.
I would not(!) like to store it as part of an app (to avoid app dependencies) but to have it in a specific place.
currently my best practice is to create a django app "shared" in which I place this code/functionality
so my project structure looks similar to this:
mysite/
manage.py
mysite/
...
shared
...
app1
...
app2
...
app3
...
...
is there a "django best parctice" or a more practical way how to handle this?
I usually do exact same thing what you are doing. Not sure if that is best practice however I've seen other people using the same approach. I like it because:
when the shared/core/etc app becomes useful in other projects, you can package it as reusable app which can be installed via pip in other projects
it does not interfere with existing apps in the project
The only note about packaging it as a reusable lib is that I would recommend to rename it to something other then shared. The reasons is that when you package it in PyPI lets say as my_django_utils, then you will have to change all your imports in all the projects. If you come up with a generic name now, then you can easily package it in the future without needing to change all your imports...
My answer is inspired by the documentation found in the edx-platform github repository: inter-app-apis
Creating a shared app seems like a good idea. However, its hard to decide whether something really needs to be in a shared app in the early days of development of a project.
If you are sharing only a small set of functionality, rather than trying to completely pull the shared code into a separate app, what if you could make it easy to manage the dependency? One problem with creating any sort of dependency is that they have a way of going out of control and very soon you wont know what parts of an app does your caller depend on.
To address this, you could define a separate python module that acts as a proxy between the app that provides the shared code and the app that calls into the shared code. So if you want your app2 to use some function foo in app1, you don't directly call that function, but you write a wrapper function foo_api in a separate module (called api.py) within app1 which calls the function for you. All functions from app1 that is called by other apps would have to go through this single api layer.
By doing this, you are not eliminating the apps depending on each other, you are making it easier to find the dependencies of an app. And if you later find that there are many callers for a function, then you could think of extracting these into a separate reusable lib.

what literally defines a django app?

I have read a few questions about what an "app" is supposed to mean in django, but they go into the general purpose/use of an app, which is important, but not what an app literally "is". For example, I felt my curiosity today when
I deleted a folder that I installed as an app with django-admin startapp, and received a certain error that stackO told me was due to a deleted app name residing in my INSTALLED_APPS. After clearing the name, my app worked again
When making a folder cold (just mkdir, no startapp) in the highest level of a project, when trying to import names from real apps, I have to add my project to the sys.path list to be able to import. After remaking this folder as an app, imports are no longer an issue
I've read questions about this topic that had comments like "OK, I've got a models.py file, so it's an app", and it seems like very few people really understand how an app is started.
My question is,
what leeway do I have to modify the apps django makes? Can I delete all the files that come with it (except init) and make it a cold library with no views and models? Are any files besides init required to function correctly?
What does django do when I run startapp that causes an app to be importable automatically, which effect is not there when I make a folder with an init in it (as I said about needing to add the project path to sys.path within that folder). In other words, what does the django command "startapp" actually do to register an app? The action is in django.core.management.templates.py, I read it today and saw things in TemplateCommand.handle() that refer to app or project names, but couldn't see exactly how it registers them. It imports sys, but searching "sys.module" isn't in the file
If I want to turn an empty directory with init into an app, what do I have to do in the shell to make this change without doing startapp?
Thank you
TLDR: Django apps are just Python packages within your project, and you don't need any file except for __init__.py to import it.
I also experienced this vague explanation of "app" from the Django docs, and it led me to look into what a "web app" in the general scheme was before I could understand the concept of a Django one when I was starting out.
Generally defined, a web application is any program transferred from server to client via a browser. This could be an entire website, a certain component in a website (think captchas, widgets, OAuth, etc.), or a function of a website (such as integration with other technologies, like exporting a page to a PDF). These can be modular components or not, portable or not, and distinct within the project's source code or mixed with other things.
Since the general "web app" definition is quite ambiguous, it may be easier to imagine the "Django app." Your project contains one or more apps, of which some may have files or not. Technically, your app can contain nothing except the __init__.py and still be imported (it's just a normal Python package, albeit a useless one). You can make it a library with other modules, but this seems unpythonic, and I make a point to separate business logic from my website source code whenever possible.
Apps are simply things that do something for your project. A question that many people, including myself, like to ask to define an app, is "what does it do?" If you can't answer this question in a concise manner (that doesn't include "and") then your app could be broken into several different parts. This is recommended for your sake, but you may break this rule if you really want. In my first Django project, I made the entire website inside one app folder. It became a nightmare to manage, but I did it.
Views and models are just places to store the information that you need to use for that app in one place; if there was just one big app for your entire website, things would get cluttered and unmanageable very quickly. That would certainly be unpythonic, and the Django developers are very conscious of making things "correctly."
As for technical specifics, Django projects are packages. You can play around with manage.py startproject and checking your sys.path before/after. Apps are packages as well, which (supposedly) contain modules that allow your "app" to perform its intended function. You can use them for anything, everything, or nothing at all, but they are just a Python package with modules in a neat little folder on your system to do something for your project.
You can find a quick overview of applications in the Django documentation here, if you haven't already. Also, this is all a product of my base understanding, so if there is any problem with any part of my answer, please let me know.

Want to run a python script on a django application

I'm working on a project that takes a web url and prints a summary of the text contents of the web page. I've written a program that does that in python and now I want to make it a web application so I decided to try django.
I've been reading the official tutorial(I'm not done, I've only gotten up to Models) but when I try to apply what I've learned and actually make the application I find myself lost.
"Where do I actually put the python code that will run on the backend?" I'm not using a database so I don't think it should be in the models.py file. Do I import it in views.py? Should I even be using django? I'm beginning to feel like it's overkill.
As you probably have seen in the tutorial, a Django project usually have several apps. Each app typically has models.py, views.py, admin.py, etc. Where to store the script depends on your project structure:
if only one app needs it, just put the script under the app
if there're several apps need the script, I mostly like will start an app called "common" or "utils", and put it there
if the script is used in multiple projects, and updated actively, I will consider make it a standalone Python package. And install it in the project's virtualenv
And where to import the script, also depends:
if the app is not complicated, no other dependency, views.py is the place to go
if the app is quite complicated that you even need to separate them into multiple views, I may create a common.py under the app to import the script
About Django or not, it depends our your (potential) project complexity:
if you project may grow big or you will use Python to write big web project, Django is worth to learn, as it's the most powerful web framework in Python
if you only need a simple web application that even doesn't need DB, Flask is simpler to learn, as Paulo said

Do I need PyISAPIe to run Django on IIS6?

It seems that all roads lead to having to use PyISAPIe to get Django running on IIS6. This becomes a problem for us because it appears you need separate application pools per PyISAPIe/Django instance which is something we'd prefer not to do.
Does anyone have any advice/guidance, or can share their experiences (particularly in a shared Windows hosting environment)?
You need separate application pools no matter what extension you use. This is because application pools split the handler DLLs into different w3wp.exe process instances. You might wonder why this is necessary:
Look at Django's module setting: os.environ["DJANGO_SETTINGS_MODULE"]. That's the environment of the process, so if you change it for one ISAPI handler and then later another within the same application pool, they both point to the new DJANGO_SETTINGS_MODULE.
There isn't any meaningful reason for this, so feel free to convince the Django developers they don't need to do it :)
There are a few ways to hack around it but nothing works as cleanly as separate app pools.
Unfortunately, isapi-wsgi won't fix the Django problem, and I'd recommend that you keep using PyISAPIe (disclaimer: I'm the developer! ;)
Django runs well on any WSGI infrastructure (much like any other modern Python web app framework) and there are several ways to run WSGI on IIS, e.g. see http://code.google.com/p/isapi-wsgi/ .

Categories