You can turn a fresh Debian machine into a running Django web app by just doing:
apt install -y python3-django apache2 libapache2-mod-wsgi-py3
And then creating the one file Django needs:/var/www/mysite/mysite/wsgi.py:
import os
import django
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.wsgi')
application = get_wsgi_application()
ROOT_URLCONF = 'mysite.wsgi'
SECRET_KEY = 'hello'
def index(request):
return django.http.HttpResponse('This is the homepage')
def cats(request):
return django.http.HttpResponse('This is the cats page')
urlpatterns = [
django.urls.path('', index),
django.urls.path('cats', cats),
]
And then telling Apache where to look for it:/etc/apache2/sites-enabled/000-default.conf:
ServerName 127.0.0.1
WSGIPythonPath /var/www/mysite
<VirtualHost *:80>
WSGIScriptAlias / /var/www/mysite/mysite/wsgi.py
<Directory /var/www/mysite/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>
And voilá, you have a running Django application, which you can expand upon to any size and complexity.If you want to try it in a docker container, you can run
docker run -it --rm -p80:80 debian:12
perform the steps above and then access the Django application at 127.0.0.1 require 'bundler/inline'
gemfile(true) do
source 'https://rubygems.org'
gem 'rails', '~> 7.1'
gem "sqlite3", "~> 1.4"
end
require 'rails'
require 'active_record/railtie'
database = 'app_development.sqlite3'
ENV['DATABASE_URL'] = "sqlite3:#{database}"
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: database)
ActiveRecord::Schema.define do
create_table :my_table, force: true do |t|
t.integer :my_table_id
end
end
class App < Rails::Application
routes.append do
root to: 'home#index'
end
end
class HomeController < ActionController::Base
def index
render inline: 'HOME'
end
end
App.initialize!
run App
For very small apps on ruby land sinatra and roda are the right choices.
On python the choice would be flask instead of the single file django. from django.db import models
from django.db import connection
class MyModel(models.Model):
name = models.CharField(max_length=255)
class Meta:
app_label = 'myapp'
with connection.schema_editor() as schema_editor:
schema_editor.create_model(MyModel)
# from django.core.management import call_command
# call_command('makemigrations', 'myapp')
# call_command('migrate', 'myapp')And not every application that uses a db needs an ORM.
You probably can build an ORM into the single file. But I'm not saying every application should be developed as a single file forever. I just like that you can start with one and expand later.
do you really consider this a lean process in 2024?
WSGI is old tech that in your example requires extra packages and code in project to work. By now Python should stand on its own and handle this independently, being proxied to by better http servers like nginx or caddy.
No it's not. Please cite reputable sources.
CPython is fully commercialized.
Despite being somewhat out of fashion, Python and Django continue to serve more down to earth software development well after so many years. I picked it up around 2007 (remember the "magic removal" branch), and it only got better ever since. Many call Python "toy language" or "data scientist language" but the truth is that 99.9% of modern web development is database-backed and, unless you have some strictly computational tasks behind your APIs, the fact that e.g. Rust is 100x "faster" than Python is mostly meaningless. Django just works. Of course, there can be different personal preferences, but I'm really amazed by the project that is closing in on 20 years that is still absolutely relevant and a joy to work with.
@tasks.cron("*/5 * * * *") # every 5 minutes
async def infrequent_task():
...
In addition Hypercorn, https://github.com/pgjones/hypercorn, (a ASGI and WSGI) also does not use gunicorn, having migrated many years ago.That said, boy does Django must change it's current strategy...
RoR and Laravel have been getting all sort of goodies baked in the framework itself such as tasks queue, nice admin features, integration with frontend technologies (scss, js, even jsx/tsx), even entire packages to manage payment systems, mailing and so on... Good quality features that are ready to use and are integrated inside the framework, which easy to use APIs and fantastic admin integration.
Django devs, on the other hand, have been (imho) ignoring the users (devs) and have been denying any and all attempts at bringing something similar to Django. There are at least half a dozen packages for each "thing" that you want to do, and some are in a very good shape, but others are just hopelessly broken. What's even worse, because they're not part of Django, most of the time there are some edge cases that just can't be implemented without subclassing Django's core.
One of the most recent examples being Django's support for async operations. Except that Django itself doesn't provide a nice way to create / expose an API, which is why people use DRF. But DRF doesn't support async, which is why you need to add "adrf" (https://github.com/em1208/adrf) to DRF. But adrf doesn't support async generic viewsets, so you must add aiodrf (https://github.com/imgVOID/aiodrf) to adrf. But aiodrf doesn't support (...) you get the point. You end up in a situation in which you're pilling packages on top of packages on top of packages just so you can have an asynchronous API. Madness.
Supporting scss it another example of pilling packages on top of packages. It just never ends...
I can't express the desire I have for Django to start integrating packages into its core and get on par with RoR and Laravel.
/rant
The biggest gripe I have with Django is that coupling it with modern UIs like Svelte and company is massively complex. The community has failed to deliver a clear guidance on how to handle implementation of such frameworks, including Vite and build steps. Which is the primary thing that drives me away from Django. I'm looking towards Laravel next. Very often, when researching how to implement JS Frameworks into Django I seem to find guidance on how to do this with Laravel and I want to know if it's really that comfy as it sounds.
Is Django-tasks the solution that would permit this to be built?
If I needed asynchronous background processing in Python today, I'd definitely be looking into `django-tasks.` If you asked me yesterday, I'd have told you I'd use SQS / whatever the platform equivalent was, or, failing that, I'd probably go with `dramatiq`.
Edit: LOL, I can't believe I forgot to mention what a fscking nightmare `celery` is to deploy and configure. UGH.
You made the wrong choice I would guess. Django does not have 'overhead' to justify in that scenario.
122370 django python=103934,javascript=18407,xml=29
2734 sqlparse python=2734
1110 asgiref python=1110
This will probably change when `django-tasks` gets merged in.Here's what installing `flask` + `sqlalchemy` pulls in:
141314 sqlalchemy python=141314
11464 werkzeug python=11159,javascript=305
8934 greenlet cpp=4993,python=2729,ansic=1092,asm=120
8606 jinja2 python=8606
5842 click python=5842
3907 flask python=3907
2036 top_dir python=2036
644 itsdangerous python=644
487 markupsafe ansic=278,python=209
349 blinker python=349
Looks like the same order of magnitude to me, which is surprising. I had always thought of `django` as being heavy weight and opinionated, while `flask` + `sqlalchemy` was light and modular.All numbers generated using David A. Wheeler's 'SLOCCount'. :-)
I am keeping the business logic separated out though so I can easily move to Django if needed.
Edit: Ooops. IPython magics don't seem to work. I hope they add it.
I wish they could make it easy to deploy django or other python framework in a serverless function with decent security baked in.