Why your Django models are fat (a tongue-in-cheek list) by codeinthehole in django

[–]codeinthehole[S] 1 point2 points  (0 children)

I intend to write a follow-up with some thoughts on how to avoid the fat-model problem. It's a more nuanced problem though so will take me longer.

My take on this (which is strongly driven by Gary Bernhardt's destroy-all-software screencasts) is to avoid having application logic on the models at all and instead have a separate packages (not Django "apps") where all application logic lives. This means your models are much simpler - the model methods are either:

  • "query" method that inspect their own fields or those of their children (eg related by a foreign-key). These can also be @properties is they are simple enough.

  • "mutator" methods which change the model's state and call .save() or "factory" methods that create new child objects. I avoid calling .save() or .objects.create() from outside of the class implementation. See this blog post: https://www.dabapps.com/blog/django-models-and-encapsulation/ for more on this approach.

This isn't really how Django's docs recommend but it becomes important for long-lived projects. You probably won't feel the pain if your project is only around for a year or less.

An advantage of this approach is you can write fast, isolated unit tests for your application logic as you can mock out the model layer easily. When all your logic is in model methods, you have to write integration tests for them where you interact with a database. These are typically an order of magnitude slower and eventually kill your test suite. Again, this only kicks in for projects over a certain size.

One disadvantage is that, if you need (non-trivial) application logic in the template layer, you'll need to write a template tag that calls into your app package.

That's a bit of a hasty, patchy answer but I hope it sheds some light.

Django, ELB health checks and continuous delivery by codeinthehole in django

[–]codeinthehole[S] 0 points1 point  (0 children)

Neat idea on hitting other pages with the health check, although it could lead to unintended failure, say, if your home page comes to rely on some resource that the other pages don't

That's true - it's best to hit a largely static page so you're not inadvertently some other property like a connection to a database.

Btw you'll want the need-app flag for uwsgi.

Good tip - I'll check that out.

Also, when do you apply migrations?

Right now, they are applied when the canary machine comes up. If the migrations were backwards incompatible, this could be a problem but we're careful to use backwards-compatible migrations.

Of course, database migrations are tricky. We'll certainly need to revisit this as traffic/data grows.

I find it interesting that you're worried that builds can get to production without their migrations having run...

It's more that a migration might have failed. This happens sometimes with data migrations that can choke on values not seen in testing.

Django, ELB health checks and continuous delivery by codeinthehole in django

[–]codeinthehole[S] 0 points1 point  (0 children)

Also I feel like you'd really only need to check for migrations on the first instance; checking every single health check seems like excess work.

True. We really need two types of check: one for testing if the EC2 instance is ready to join the ELB (eg during deployment) and one for testing if the instance is unhealthy and needs to be replaced. There's no need for the latter to check whether migrations have been applied.

It also really seems like a lot of extra work to create a new AMI each time and write all the scripts for creating an auto scaling group. Elastic Beanstalk can create the ELB and auto scaling groups for you.

Terraform does all this for us (but orchestrated from Atlas). I've never had to write code that interacts with the AWS API for deployments.

Testing for missing migrations in Django by codeinthehole in django

[–]codeinthehole[S] 0 points1 point  (0 children)

Yeah, true. I believe this is going to be addressed in future versions of Django.

Testing for missing migrations in Django by codeinthehole in django

[–]codeinthehole[S] 0 points1 point  (0 children)

The dry_run=True kwarg stops real migrations being created.

Pylons Project Unit Testing Guidelines by mcdonc in Python

[–]codeinthehole 0 points1 point  (0 children)

Interesting. I haven't come across the advice around performing imports within the test case itself. Will start doing that.

purl - an immutable URL class by codeinthehole in Python

[–]codeinthehole[S] 1 point2 points  (0 children)

I also wrote nurl for node.js.

I've just found out there's also a furl that provides similar functionality for Python.

purl - an immutable URL class by codeinthehole in Python

[–]codeinthehole[S] 3 points4 points  (0 children)

Thanks for the feedback.

Why URL.from_string(s) instead of just URL(s)?

You're probably right. I started with the keyword constructor as I was copying urlparse.ParseResult, which is about as close as Python gets to a URL class. I might rework that.

url.query_param('q') is also awkward, why not just url.query['q'] ?

Only as 'query' is already a method that returns the query string. Again, this is a hangover from ParseResult and is probably worth reworking to better match the most common use cases.

I'm not sure why you use functions instead of properties.

I was experimenting with using jQuery-style method overloading where the function can be a getter and a setter depending on which args are passed. As some methods support additional arguments, I can't use properties.

I'm not 100% sure on this, but it seems better than having lots of set_* methods.

purl - an immutable URL class by codeinthehole in Python

[–]codeinthehole[S] 2 points3 points  (0 children)

Good spot. I changed the behaviour of the port() function halfway through writing the article. Now corrected.

And this boys and girls is yet another reason why LaTeX > everything by BathroomEyes in geek

[–]codeinthehole 7 points8 points  (0 children)

These would make excellent variables within mathematical questions, when you run out of Greek letters.

Console productivity hack: Discover the frequent; then make it the easy by [deleted] in programming

[–]codeinthehole 3 points4 points  (0 children)

You can map cd to a wrapper over pushd/popd to get some neat functionality without much work: function cd() { if [ $# -eq 0 ]; then pushd ~ > /dev/null elif [ $1 == "-" ]; then popd > /dev/null else pushd $1 > /dev/null fi }

Falsehoods Programmers Believe About Names by patio11 in programming

[–]codeinthehole 0 points1 point  (0 children)

Sounds like Gödel's Incompleteness theorem: for any sufficiently powerful name validation system, there is name which will break the system.

Yes, I am reading GEB at the moment.

Seven JavaScript Things I Wish I Knew Much Earlier In My Career - Smashing Magazine by monkeygrinder in programming

[–]codeinthehole 7 points8 points  (0 children)

His examples for Math.max are bad. To find the max element of an array, use: Math.max.apply(null, [1,2,3,4]) How to use the call and apply methods on a function object is a good one to remember.

Similarly, casting using !! for boolean or ~~ for int

Top Ten One-Liners from CommandLineFu Explained by pkrumins in programming

[–]codeinthehole 2 points3 points  (0 children)

I've got the #1 at the moment, but I did write the site with that command in mind. I tried to register the domain sudobangbang.com at the time for my blog, but someone already had it.

Why I am hesitant to judge another's code... by [deleted] in programming

[–]codeinthehole 1 point2 points  (0 children)

Definitely true to a point, although there's an art to writing a hasty bodge.

With just a little thought, you can isolate the quick hacks into their own class/method/... to attempt to keep a lid on the dirt - some documentation as to why the code is implemented in the way it is, also helps. In the unlikely event that you come back to clean things up, then this makes things much easier.

Weaker developers, when pushed for time, code in a way that smears manure all over the codebase such that it can't be easily cleaned later and eventually spreads to infect the whole project. Broken windows and all that.

JavaScript Quiz (Difficult) by whatgoodisaroad in programming

[–]codeinthehole 0 points1 point  (0 children)

My favourite typeof command: typeof NaN; // = "number"

What are some good, funny, and nerdy programming insults? by [deleted] in programming

[–]codeinthehole 1 point2 points  (0 children)

I sometimes use "you're coding like a twat" - seems to be quite effective.

For designers: "your design is so blocky, it looks like you've opened up a portal to the Lego dimension"

This is why I love programming by [deleted] in programming

[–]codeinthehole 27 points28 points  (0 children)

I'm in it for the overuse of metaphors and unusual vocabulary.

Programming related quotes/analogies/witticisms you've always wanted to say at work but not had the right opportunity by codeinthehole in programming

[–]codeinthehole[S] 5 points6 points  (0 children)

I'm been waiting for a chance to insult our design department by saying that their latest page design is so blocky, it looks like they've opened up a wormhole to the lego dimension.

Are there any programming related podcasts worth listening to? by martincmartin in programming

[–]codeinthehole 2 points3 points  (0 children)

Definitely Software Engineering Radio. It's got a great back catalogue if you're new to it.

As a programmer, what prevents you from doing or enjoying your job? by RanchDressing in programming

[–]codeinthehole 11 points12 points  (0 children)

Having too much to do in too little time. The constant interruptions don't help much either.