Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

They are excellent! Another great example is the Django project, which I always point to for how to write and structure great technical documentation. Working with Django/Postgres is such a nice combo and the standards of documentation and community are a huge part of that.


Interestingly I have had almost the exact opposite experience being very frustrated with the Django docs.

To be fair, it could be because I'm frustrated with Django's design decisions having come from Rails.

When learning Django a few years ago, I still carry a deep loathing against polymorphism (generic relations[0]), and model validations (full clean[1]),

You know what - it's design decisions...

[0] https://docs.djangoproject.com/en/5.1/ref/contrib/contenttyp...

[1] https://docs.djangoproject.com/en/5.1/ref/models/instances/#...


generic relations are hard to get right, really if you can avoid using them you're going to avoid a lot of trickiness.

When you need them... it's nice to have them "just there", implemented correctly (at least as correctly as they can be in an entirely generic way).

Model validations is a whole thing... I think that Django offering a built-in auto-generated admin leads to a whole slew of differing decisions that end up coming back to be really tricky to handle.


Would love to hear more about what you don't like with model validations (full clean).


Sorry on the slow reply.

But yea, I can complain at length.

- Model validations aren't run automatically. Need to call full_clean manually.

- EXCEPT when you're in a form! Forms have their own clean, which IS run automatically because is_valid() is run.

- This also happens to run the model's full_clean.

- DRF has its own version of create which is separate and also does not run full_clean.

- Validation errors in DRF's Serializers are a separate class of errors from model validations and thus model Val Errors are not handled automatically.

- Can't monkey patch models.Model.save to run full_clean automatically for because it breaks some models like User AND now it would run twice for Forms+Model[0].

Because of some very old web-forum style design decisions, model validations aren't unified thus the fragmentation makes you need to know whether you're calling .save()/.create() manually, are in a form, or in DRF. And it's been requested to change this behavior but it breaks backwards compat[0].

It's frustrating because in Rails this is a solved problem. Model validations ALWAYS run (and only once) because... I'm validating the model. Model validations == data validations which means it should be true for all areas regardless of caller, except in exceptions, then I should be required to be explicit when skipping (i.e. Rails) where as in Django I need to be explicit in running it - sometimes... depends where I am.

[0] https://stackoverflow.com/questions/4441539/why-doesnt-djang...


Thanks for your reply. I'm currently in a stage of falling out of love with Django and trying to get my thoughts together on why that is.

I think Django seems confused on the issue of clean/validation. On the one hand, it could say the "model" is just a database table and any validation should live in the business logic of your application. This would be a standard way of architecting a system where the persistence layer is in some peripheral part that isn't tied to the business logic. It's also how things like SQLAlchemy ORM are meant to be used. On the other hand, it could try to magically handle the translation of real business objects (with validation) to database tables.

It tries to do both, with bad results IMO. It sucks to use it on the periphery like SQLAlchemy, it's just not designed for that at all. So everyone builds "fat" models that try to be simultaneously business objects plus database tables. This just doesn't work for many reasons. It very quickly falls apart due to the object relational mismatch. I don't know how Rails works, but I can't imagine this ever working right. The only way is to do validation in the business layer of the application. Doing it in the views, like rest framework or form cleans is even worse.


Yeah definitely understand the frustration. I've been there and while I don't think we've found _the_ solution, we've settled into a flow that we're generally happy with.

For us we separate validations in two. Business and Data validations, which are generally defined as:

- Business: The Invoice in Country X is needs to ensure Y and Z taxes are applied at Billing T+3 days otherwise throw an error.

- Data Validation: The company's currency must match the country it operates in.

Business validations and logic always go inside services where as data validations are on the model. Data validations apply to 100% of all inserts. Once there's an IF statement segmenting a group it becomes business validation.

I could see an argument as to why the above is bad because sometimes it's a qualitative decision. Once in a while the lines get blurry, a data validation becomes _slightly_ too complex and an arguement ensues as to whether it's data vs business logic.

Our team really adheres to services and not fat models, sorry DHH.

To me, it's all so controversial whatever you pick will work out just fine - just stick to it and don't get lazy about it.


Services are definitely better and a solid part of a domain-driven design. The trouble is with Django I think it's a bandaid on a fundamentally broken architecture. The models end up anaemic because they're trying to be two things at once. It's super common to see things like services directly mutating model attributes and set up relationships manually by creating foreign keys etc. All of that should be hidden far away from services.

The ultimate I think is Domain-Driven Design (or Clean Architecture). This gives you a true core domain model that isn't constrained by frameworks etc. It's as powerful as it can be in whatever language you use (which in the case of Python is very powerful indeed). Some people have tried to get it to work with Django but it fights against you. It's probably more up front work as you won't get things like Django admin, but unless you really, truly are doing CRUD, then admin shouldn't be considered a good thing (it's like doing updates directly on the database, undermining any semblance of business rules).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: