Settings

Theme

Building a full Django project, starting with a single file

mostlypython.com

121 points by kqnrnq17r 2 years ago · 54 comments

Reader

simonw 2 years ago

I'm a big fan of the single-file Django ambition - it's the feature I most envy from frameworks like Flask and Starlette.

I actually had a go at this myself 15 years ago, with a project I called Djng: https://github.com/simonw/djng - more details on that here: https://simonwillison.net/2009/May/19/djng/

  • radiac 2 years ago

    Me too, I'm convinced it has a place - the number of single file projects over the past few years can't be a coincidence.

    For me the two missing pieces were models and a path to migrate to a full project once it outgrew a single file, so I wrote nanodjango (https://github.com/radiac/nanodjango/, formerly django-flasky) - you can use the ORM and admin site, and I recently added a "convert" command to automatically break up a single page app into a full Django project structure.

    I've been using it for a couple of years for prototyping/experimenting and putting together small apps, and with the new features this year feels like it's a really practical alternative to flask.

    • creshal 2 years ago

      > I'm convinced it has a place - the number of single file projects over the past few years can't be a coincidence.

      The human soul yearns for the simplicity of php or cgi-bin hosting, without the horrors of PHP or C

      • radiac 2 years ago

        Mine certainly does - we lost so much when we killed off our cgi-bin/guestbook.pl

    • selcuka 2 years ago

      This looks really cool, congratulations.

      Are you planning to add some kind of API serving functionality (either by integrating something like Django Ninja or even raw Pydantic)? I think such single file frameworks are great candidates to implement microservices.

      • radiac 2 years ago

        Thanks! Yes definitely, I think it's a great fit for anything self-contained and limited scope that doesn't need a lot of code. I've certainly found having an easy way to run a single file using Django's ORM is pretty handy.

        Regarding API serving, I'm planning on making it easier to use third party apps; the main obstacle is registering `includes` urls, which is doable at the moment but involves manually appending a path to `nanodjango.urls.urlpatterns`. I want to expand route registration to give a nicer internal api, then once that's in place Django Ninja should work pretty much out of the box - the only different should be how you register the url.

    • pjerem 2 years ago

      This looks amazing ! Bravo

  • BeefySwain 2 years ago

    I would be interested to hear your thoughts on why this never ended up going anywhere? (Or did it go somewhere ?)

    As a Django user that shares your frustrations with settings.py, I wish this had panned out.

    • simonw 2 years ago

      I got very busy at work, then quit to go on honeymoon, then accidentally started a startup!

      I wasn't particularly good at sticking with open source projects like this and pushing them forwards back in 2009. I've since learned how to do that but it took me another decade to get there.

      • BeefySwain 2 years ago

        Is this something you think you would ever come back to?

        • simonw 2 years ago

          Honestly no - not at this point. I have too many other projects on the go. I'd love to see the Django community take this on generally - there are a bunch of people interested in it, hopefully that result in a long-term stable project around the idea.

sireat 2 years ago

Fantastic idea to start Django with a single file!

Some years back when I had to do some quick and dirty projects, I chose to go with Flask because of how dirt simple it was to start.

All the Django books and tutorials had this hidden magic abstraction feel to them after:

  $ django-admin startproject <project-name> .
  $ python manage.py startapp <app-name>

Once you've reinvented half the Django functionality in Flask (using SQLAlchemy etc) you realize the need for the most of these abstractions.
Onavo 2 years ago

The most powerful part of Django is its ORM, nothing else comes close in the ecosystem. The automatic migration generation tools for SQLAlchemy like alembic are much harder to use than django's built-ins.

Django just needs to add Pydantic integration.

  • fleetfox 2 years ago

    In what way "most powerful"? If you do anything more involved than CRUD it falls apart pretty fast. You can't express most of the things you can do with raw SQL since there is not intermediate DSL like you do with SQLA. You can't hydrate arbitrary object graphs. It's slow, for deep queries building back objects is slower than actual SQL round trip.

    It's very easy to use but it's also very limited and i often find myself dropping down to RawSQL or even having SQLA connection in my Django projects.

    • SheepSlapper 2 years ago

      Then you might not be in the target audience of Django. For the rest of us, the ORM is dope as hell and nobody cares that you aren't writing the most performant SQL the world has ever seen...

      • rossant 2 years ago

        The ORM is fantastic and I never use raw SQL, but I can see how it may be simpler to just go straight to raw SQL with complicated database structures and queries.

        • Maxion 2 years ago

          The best part about it though is that you can use raw SQL and the ORM at the same time. In larger projects that's how I've always used it. ORM for the majority of use cases, and the raw SQL where performance really matters.

    • selcuka 2 years ago

      Which other Python based ORM addresses those issues?

      • fleetfox 2 years ago

        SQLAlchemy does. I get that DjangoORM is more convenient and might be good enough. But powerful seems like wrong adjective.

        • winrid 2 years ago

          Powerful in terms of productivity. The occasional N+1 query problem here and there isn't a big issue for many projects and means you can launch 10x faster than someone using some other technologies. If you're successful, you can easily write raw SQL and optimize as needed.

        • pjerem 2 years ago

          DjangoORM isn’t perfect but its power comes from the fact it is heavily integrated with Django (the framework).

        • selcuka 2 years ago

          Ah, sorry. It wasn't clear that SQLA meant SQLAlchemy in your first comment.

  • dhruvkb 2 years ago

    I have a few projects where I use Django just for the ORM. The rest of the project is is CLI commands that are being run as Django's management commands to be able to access the ORM models. SQLAlchemy and alembic are quite far behind compared to Django.

  • axit 2 years ago

    There are couple of projects aiming to integrate django & pydantic: https://django-ninja.dev for APIs & https://github.com/jordaneremieff/djantic for model data

  • jamestimmins 2 years ago

    Few things I want more than for someone to extract the Django ORM from Django so we can use it standalone instead of SQLAlchemy

  • wilsonfiifi 2 years ago

    Have you taken a look at Masonite Framework's ORM [0]? It's an implementation of ActiveRecord. I'm not sure why the framework [1] doesn't get enough attention though. I think it's a nice option for projects that have outgrown Flask but aren't keen on Django.

    [0] https://orm.masoniteproject.com/

    [1] https://docs.masoniteproject.com/

  • konschubert 2 years ago

    I was thinking the same the past few days.

    Going with fastapi and sqlalchemy, there is no django admin and no user management out of the box.

    But writing serialisers for DRF feels dated.

    • SCUSKU 2 years ago

      Would highly recommend you check out Django Ninja as well as Django Ninja Extras. Having done Flask + FastAPI dev then Django, Django Ninja brings the modern feel of FastAPI to the battle tested reliability of Django.

    • alumic 2 years ago

      I’ve been very happy with Django ninja. It brings in pydantic as well so you get the benefit of type safety in addition to a much faster request response cycle as compared to DRF

    • Maxion 2 years ago

      You can quite easily generate typescript models from DRF serializers, that helps a lot when setting up a frontend project against a DRF api.

  • hsbauauvhabzb 2 years ago

    Agree, I never felt comfortable with sqlalchemy, but I don’t need most other django features and find mTLS elf wrestling against them

  • ipaddr 2 years ago

    I'm using Orator as a replacement and enjoying the experience.

whatever1 2 years ago

I really love Django. I knew nothing about web development, it took me by the hand and from a tutorial I went to a full fledged application.

I cannot fathom what is the GDP impact that these folks enabled.

  • rossant 2 years ago

    After more than a decade building custom admin-like interfaces from scratch in PHP, the auto-generated admin interface in Django felt like magic.

    • SCUSKU 2 years ago

      Django admin + the Django ORM are the biggest reasons I haven’t moved to JavaScript Metaframework land. Next.js is great in its support of react and server rendered react for SEO. But where Django wins is that logic will always have to be on the trusted compute environment, the server. JS Metaframeworks approached the full stack problem from the front end and Django from the backend.

jarpineh 2 years ago

I'd love to use Django as a fast and easy single file app. There's some great looking solutions here. Have to take a look.

I tried myself about five years ago. My idea was to make a tool that could make a HTTP service from any Python file with very simple setup. With all the features of Django at the ready. Unfortunately neither Django's configuration system nor Python import methods made it reliable enough. Or I just couldn't hack it. This was the smallest I managed:

  from django.urls import path
  from django.http import HttpResponse

  CONF = {
    "INSTALLED_APPS": ["serverless"],
    "ROOT_URLCONF": (path("", lambda x: HttpResponse("look ma, no server")),),
    "DEBUG": True,
    "SECRET_KEY": "randobrando"
  }
Other thing I tried to do with this was attach a Jupyter kernel. This way I could change the code as I went, but wouldn't have to use entire Jupyter client stuff. Unfortunately there I ran into problems with event loops. I could not find a way to manage different servers in the same runtime instance. Perhaps it's time to try again wiser and helped by LLMs...
  • japhyr 2 years ago

    The app-based model is really baked into Django. As we've seen from a bunch of examples, especially recently, it's not too hard to build out a single-file project that serves a simple home page with a brief message. As soon as you want to support a full actual page, and a set of pages, you really have to figure out a well-thought-out plan for how people will expand the project.

    If you're still interested in this work, I suggest checking out nanodjango, which was mentioned earlier in this thread. That project is new, but there's a plan from the outset for how people can transition from the single-file based version to a standard Django project. You might also want to check out Andrew Godwin's django-singlefile project. It's meant to support small flask-like projects, where you don't have any intention of expanding out into a standard Django project.

    Both of these projects have their own code that takes what's included in the small file and tells Django how to make sense of it. That's much different than the projects that are only trying to make use of what's included in Django itself.

    (I'm the author of the Django from first principles series that was submitted here, but I didn't see it on HN until this morning.)

    nanodjango: https://github.com/radiac/nanodjango

    django-singlefile: https://github.com/andrewgodwin/django-singlefile

    • jarpineh 2 years ago

      Thank you for your reply. For the first point, I agree. When I was doing my experiments with single file Django I was thinking of combining few simple, single purpose apps into one regular Django project. This project would serve as an actual site for people to use with its own templates, but hopefully not that much custom code. With ASGI coming along (this was 2019 I think) I even tried to combine these app pieces under one ASGI server. Sadly I run into some trouble with server tooling.

      In regards to nanodjango I shall take a look. Also, need to read the rest of your articles. Thank you for writing them! I’d still like to experiment with the idea of small, independent, pluggable apps. Perhaps Django can be coaxed to this now.

wilsonfiifi 2 years ago

Lightweight Django (2014) [0] actually explores using the Django framework in a similar manner.

[0] https://www.oreilly.com/library/view/lightweight-django/9781...

seper8 2 years ago

Am I missing something or is there no sample code...?

thedeparted_one 2 years ago

Awesome!

xcdzvyn 2 years ago

I really wish there were something like this for Phoenix. I want to like it, but I feel a little inundated with all the codegen.

  • agos 2 years ago

    I second the feeling. It's really hard to tell what is (are?) the entry point and where does the flow go

    • arcanemachiner 2 years ago

      If you use all the `--no-` flags (e.g. `--no-tailwind`) when creating a Phoenix project, you will be left with a surprisingly small amount of code.

      This is not so useful in a real project, but good as a learning exercises to see what comprises the core of a Phoenix application.

      https://hexdocs.pm/phoenix/Mix.Tasks.Phx.New.html

      FWIW, everything starts in your project's `lib/project/application.ex` file. All the things in the `start` function dictate the "flow" of the application.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection