Live data from Hacker News

Tips for Building High-Quality Django Apps at Scale

blog.doordash.com

81–90 of 125 posts

Re: Tips for Building High-Quality Django Apps at Scale

#81
post #77

Earlier quoted context omitted.

Part of it is that Django has been around for quite a while now. It's maybe _the_ most succesful Python framework out there, so there are some paradigms that aren't common anymore but are hold-overs from years past. In particular, it pre-dates the current "microservice" trend and assumes a fairly monolithic environment. And I think "apps" _do_ make sense in certain contexts. Consider this situation: - I start a "poll…

Is it actually possible to find and drop in apps like you suggest? And have it just work? Is a repository of various blog apps out there? What if one of them does something nasty to your database? It seems like it'd be easier to spin up a Wordpress instance...

Yes, there's a whole universe of them.

Here's a good place to start looking for things to help make development easier:

https://djangopackages.org/

Re: Tips for Building High-Quality Django Apps at Scale

#82
post #77

Earlier quoted context omitted.

Part of it is that Django has been around for quite a while now. It's maybe _the_ most succesful Python framework out there, so there are some paradigms that aren't common anymore but are hold-overs from years past. In particular, it pre-dates the current "microservice" trend and assumes a fairly monolithic environment. And I think "apps" _do_ make sense in certain contexts. Consider this situation: - I start a "poll…

Is it actually possible to find and drop in apps like you suggest? And have it just work? Is a repository of various blog apps out there? What if one of them does something nasty to your database? It seems like it'd be easier to spin up a Wordpress instance...

> What if one of them does something nasty to your database?

Same question is valid for Wordpress plugins.

Re: Tips for Building High-Quality Django Apps at Scale

#83

I'm so glad to see the mention of "app" directories here. I've only dabbled in Django development, but I've always thought the desire to divide things into apps didn't really make any sense. It felt like the developers of Django had said "well, intuitively, there must be some unit of reuse at this level" and then stuck the notion of apps in there in an attempt to provide that reuse. This seems to me to be somewhat un…

A good rule of thumb is that a Django "app" should be (1) standalone and (2) reusable.

If you were to write a Django project to automate some complicated internal process at your particular company, it's likely that you'd break up the code into separate Python modules to help give it an easy to understand structure. But it's unlikely that any other company would necessarily benefit from any of those separate modules by themselves.

However, let's say you come up with a clever idea about how to log errors in your project. Now, that's the sort of thing that other people might want to use in their own projects. If you were to restructure your code a bit and make it a bit more abstract then you could create a separate "app" that could be dropped into other Django projects.

Re: Tips for Building High-Quality Django Apps at Scale

#85
post #70

Earlier quoted context omitted.

> Avoiding "fat models" is another place where it feels more like opinion than anything to do with performance or good design So in the Java world, the general pattern is that: Views: - Accept and sanitize query parameters - Call call one or more service methods. - Catch errors and return an appropriate error response - Render a JSON response based on the results of the service methods if nothing goes wrong. Service…

Is there a good place or pattern for service methods in Django? I've got some very fat models right now, and it's a DRY improvement over having the fat in the views, but like you say it takes a lot of effort to trace what's going on.

Let's say you're following the approach of breaking down your project into separate apps, so you have an app called user_accounts. This app would be a folder containing files like:

  views.py, services.py, models.py, test_views.py
So in views.py you'd have a User class, with:

  A POST method that calls services.create_user(username, email_address, password)

  A GET method that calls services.get_user_profile(request.user)

  A PUT method that calls services.update_user_profile(x, y, z)

  A DELETE method that calls services.inactivate_user(request.user)
The return value of each of these views can just be whatever services.get_user_profile(request.user) returns, rendered into JSON.

Then each of the services performs whatever business logic it needs to, preferably directly in the method. But if it would be more readable split into multiple methods, then you can create some private helper methods in the services file prefixed with an underscore. You can also have a separate folder somewhere for utility functions meant to be reused across the app, e.g. get_user_emails(request.user, is_active=True, is_verified=True)

Basically though each view sanitizes the data, e.g. strips XSS out of strings, makes sure booleans are actually booleans, etc.

Then each service first does field-level validation with serializers, e.g. ensuring that usernames meet the appropriate requirements for usernames. Next if there is other business logic validation that needs to happen, it happens, e.g. making sure that only users with verified email addresses can perform certain actions.

After that you perform the actual business logic, e.g. transforming any data. Then you perform your CRUD operation, e.g. creating a user model. And lastly you return something, e.g. returning the user model.

Each endpoint and service method can be written pretty much following this pattern, which makes the codebase super readable because once you understand one endpoint you understand all of them. And the service methods are the reusable component of the architecture, so e.g. if you want the ability for admins to create users, then they are created with the exact same service method. (But called from your admin endpoints/services.)

Re: Tips for Building High-Quality Django Apps at Scale

#86
post #21

Earlier quoted context omitted.

I do appreciate some of the sentiment here. "Organize your apps inside a package", "Keep migrations safe", "Don't cache models" and "Avoid GenericForeignKey" are the ones I agree the most with, so I'll go over some of the others. Some of the other migration-related ones I don't have a strong opinion on... > If you don’t really understand the point of apps, ignore them and stick with a single app for your backend. You…

I found signals (especially post_save hooks) incredibly useful for updating related models and caches. Their rational for avoiding them was weak.

Django signals are too magical, and very difficult to debug

We've had too many cases of phantom bugs which turned out to be caused by an errant signal in some distant unrelated model.

Re: Tips for Building High-Quality Django Apps at Scale

#87
post #51

Earlier quoted context omitted.

If you're leaning on migrations often, with SQL, then I think you should not be using SQL, obviously (or you're just doing something wrong) Or, one should use a SQL database that allows more abstract data types (like JSON blobs in Postgres)

So where is your data model enforced if not in your tables?

> So where is your data model enforced if not in your tables?

It's enforced...

...in the models.

:P

Re: Tips for Building High-Quality Django Apps at Scale

#88

Earlier quoted context omitted.

Yes, that's what I said...?

Sorry, misread that line. Point being, how many examples do you have where someone writing a Django site is going to reuse their own apps?

I reuse my own apps constantly, whenever I do new sites.

Re: Tips for Building High-Quality Django Apps at Scale

#89
post #52
post #37

Earlier quoted context omitted.

Yeah, pretty much. Haven't had a problem yet where I needed automated migrations, and I have been doing this for years upon years upon years. Like I said, if you're leaving heavily on migrations, you're doing something wrong.

Haven't had a problem yet where I needed automated migrations, and I have been doing this for years upon years upon years. Just out of curiosity, have you had to maintain/modify any of these apps over these years and years? If so, without any schema changes?

> Just out of curiosity, have you had to maintain/modify any of these apps over these years and years?

Absolutely.

> If so, without any schema changes?

Usually, to be honest, yeah... Core, basal units of any given business process usually don't change. Only how they are abstracted, and that abstraction lives in code, not the database.

With a proper storage architecture it is very very very rare to need to change old data structures. It most definitely doesn't happen often enough to necessitate the use, overhead, and complexity of a baked-in migrations library.

If you think "adding a table" or "adding a field" is a "schema change" then that is where the problem lies... I think. Extending a schema should not require a migration library. CHANGING a schema, as in, destroying old data, and making new data, could surely use the help of a migration library, but, generally, if you're doing that often, you're doing something very wrong, and if you're not doing that often, then you definitely don't need a baked in migration library.

Ultimately, if things are so bad that you need a migrations library, you're better off fixing that shit at a low level, and starting over from scratch if necessary. Sometimes, instead of creating years and years of tech debt and burning resources on working with a clusterfuck, you just need to take what you can from that clusterfuck, and do it right. Then you only have a single migration, to go from old clusterfuck data to new extensible data structure.

Chances are, if you have old fucked up horrific data, it stays that way, and then some person or team comes along and writes a nice clean API on top of it. And then people have to maintain that horrific thing, and it's only horrific because it's interfacing with shit data layers in the first place.

Don't just abstract bad data architecture away into a service layer, is my point... Do it right.

Extensible is the key word here, but with an emphasis on decoupling.

If you have some dynamical data structure that is truly changing, structurally, often, and isn't simply being appended to or extended, then it probably should not be stored in a traditional SQL database in any way that necessitates schema changes. If you can't figure out how to represent data in an effective, decoupled, and extensible manner, then you're screwed from the get-go. Migrations library won't help you.

Re: Tips for Building High-Quality Django Apps at Scale

#90

I'm so glad to see the mention of "app" directories here. I've only dabbled in Django development, but I've always thought the desire to divide things into apps didn't really make any sense. It felt like the developers of Django had said "well, intuitively, there must be some unit of reuse at this level" and then stuck the notion of apps in there in an attempt to provide that reuse. This seems to me to be somewhat un…

You could write a Django site in a single file if you wanted to.

See this for an example: https://www.safaribooksonline.com/library/view/lightweight-d...

Post reply on HN