<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Matt Robenolt</title>
 <link href="https://mattrobenolt.com/atom.xml" rel="self"/>
 <link href="https://mattrobenolt.com/"/>
 <updated>2022-01-22T01:48:56+00:00</updated>
 <id>https://mattrobenolt.com/</id>
 <author>
   <name>Matt Robenolt</name>
   <email>m@robenolt.com</email>
 </author>

 
 <entry>
   <title>Things I Learned About Being a Software Engineer</title>
   <link href="https://mattrobenolt.com/things-i-learned-about-being-a-software-engineer/"/>
   <updated>2014-01-07T00:00:00+00:00</updated>
   <id>https://mattrobenolt.com/things-i-learned-about-being-a-software-engineer</id>
   <content type="html">&lt;h1 id=&quot;things-i-learned-about-being-a-software-engineer&quot;&gt;Things I Learned About Being a Software Engineer&lt;/h1&gt;

&lt;p&gt;Since I started working at Disqus a year ago, I feel that I’ve grown more as an engineer than I have the rest of my career combined.&lt;/p&gt;

&lt;p&gt;For the first time in my career, I’ve been spending some time to reflect and look back on what has changed and how I got to this place. There is one critical point that has stood out to me that has changed my perspective on how I tackle problems and interact with our team.&lt;/p&gt;

&lt;h2 id=&quot;i-dont-actually-know-what-im-doing&quot;&gt;I don’t actually know what I’m doing&lt;/h2&gt;

&lt;p&gt;I like to think that I’m a relatively accomplished individual. I’ve been writing code in some shape or form for the past almost 18 years. The one thing that I’ve learned is that &lt;em&gt;I actually suck at this programming thing&lt;/em&gt; and I have literally no idea how anything actually works.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When I was a young kid and everything was new to me, learning all this shit was an amazing experience. Honestly, nothing in my life has given me the same joy or the same feeling. As I got older, that started to wear off. The foundation of my skills had been laid and I began to hone my skills more and more. Sure, I was still learning a lot, but the pace had slowed down. I sorta figured out what all this code stuff was and things started to actually make sense. I could build new things from scratch and all of that good stuff.&lt;/p&gt;

&lt;p&gt;From this point, my confidence started to grow and grow. Up until a few years ago, I was feeling like I was at a pretty high point in my skillset and grew overconfident.&lt;/p&gt;

&lt;p&gt;As a result of being overconfident, I started making critical and sloppy mistakes. I stopped asking questions. I knew how to do this, it’s easy! This lead to several critical mistakes and lots of lessons learned.&lt;/p&gt;

&lt;p&gt;Since then, I’ve begun to realize that the more I learn, the less I actually know about all of this. And that’s ok. Every time I learn something new, I feel like I’ve opened a door into a brand new world of things I’ve never dealt with before.&lt;/p&gt;

&lt;h2 id=&quot;cool-story-bro-why-are-you-telling-me-this&quot;&gt;Cool story bro, why are you telling me this?&lt;/h2&gt;

&lt;p&gt;Understanding this has caused me to tackle problems and work with others differently.&lt;/p&gt;

&lt;h3 id=&quot;1-make-crazy-changes-but-be-cautious&quot;&gt;1. Make crazy changes, but be cautious&lt;/h3&gt;

&lt;p&gt;Since I have no idea how anything works, I’ve learned more that &lt;em&gt;anything&lt;/em&gt; can happen and I’m probably not really going to understand. I’ve learned enough to be as defensive as possible. Anything that can go wrong, will go wrong and we don’t want to bring down the whole service. Sometimes dangerous and radical changes need to happen, and it’s safer to assume it’s going to fail 100%. So just plan for that, then iterate. Overall my risk assessment skills have skyrocketed as a result of accepting that I know nothing about how anything works.&lt;/p&gt;

&lt;h3 id=&quot;2-ask-more-questions&quot;&gt;2. Ask more questions&lt;/h3&gt;

&lt;p&gt;Other people are smart. Why spend a lot of time trying to figure something out on your own or re-inventing something when someone smarter has done it already? People will gladly help you if you ask enough.&lt;/p&gt;

&lt;h3 id=&quot;3-not-knowing-everything-is-really-fine&quot;&gt;3. Not knowing everything is really fine&lt;/h3&gt;

&lt;p&gt;I don’t need to know everything to do awesome things. Understanding the risks involved is much more important than actually knowing. Make things up. Have fun. But cover your ass. Nobody is going to complain about a broken experiment if that experiment isn’t affecting anything. Once your ass is covered, try whatever you want! This is the opportunity to learn if your crazy idea is actually meaningful.&lt;/p&gt;

&lt;h2 id=&quot;ending-thoughts&quot;&gt;Ending thoughts&lt;/h2&gt;

&lt;p&gt;In retrospect, this realization seems like common sense to me. It has taken me almost 18 years to figure out that computers are really hard and I’ve learned how to embrace it. I hope this insight helps someone out. I’ve been very fortunate in my career so far to have some awesome mentors by my side, and I’m very thankful for having worked alongside them all.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Announcing: Raven.js 1.0</title>
   <link href="https://mattrobenolt.com/raven-js-1-0/"/>
   <updated>2013-01-27T00:00:00+00:00</updated>
   <id>https://mattrobenolt.com/raven-js-1-0</id>
   <content type="html">&lt;h1 id=&quot;announcing-ravenjs-10&quot;&gt;Announcing: Raven.js 1.0&lt;/h1&gt;
&lt;p&gt;If you’ve used &lt;a href=&quot;https://github.com/getsentry/raven-js&quot;&gt;Raven.js&lt;/a&gt; in the past, I’m sorry. It probably didn’t work well, and you probably ended up with a ton of strange &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Script Error.&lt;/code&gt; logs.&lt;/p&gt;

&lt;p&gt;&lt;abbr title=&quot;January 27th, 2013&quot;&gt;Today&lt;/abbr&gt;, I’m excited to announce a full rewrite of &lt;a href=&quot;https://github.com/getsentry/raven-js&quot;&gt;Raven.js&lt;/a&gt; with the goal of &lt;em&gt;actually&lt;/em&gt; making stack traces in JavaScript meaningful.&lt;/p&gt;

&lt;p&gt;Throughout this process, I’ve learned much more about error handling in JavaScript than I’ve ever wanted to, and in turn, learned how equally terrible it is.&lt;/p&gt;

&lt;p&gt;One of the goals with 1.0 is, in general, a much better understanding of &lt;em&gt;why&lt;/em&gt; things weren’t working right and figuring out solutions, either on our end or yours, to make the errors as meaningful as possible.&lt;/p&gt;

&lt;p&gt;Also, from this point on, I’m personally committed to making &lt;a href=&quot;https://github.com/getsentry/raven-js&quot;&gt;Raven.js&lt;/a&gt; the best tool for debugging client side exceptions, and I encourage &lt;a href=&quot;https://twitter.com/mattrobenolt&quot;&gt;sending me feedback&lt;/a&gt; and &lt;a href=&quot;https://github.com/getsentry/raven-js/issues&quot;&gt;reporting issues and ideas to make the project better&lt;/a&gt;. It’s very hard to identify every scenario in every browser alone!&lt;/p&gt;

&lt;p&gt;If you are using &lt;a href=&quot;https://getsentry.com&quot;&gt;GetSentry&lt;/a&gt;, you can begin trying out the new &lt;a href=&quot;https://github.com/getsentry/raven-js&quot;&gt;Raven.js&lt;/a&gt; today. If not, you’ll want to upgrade to Sentry 5.3.&lt;/p&gt;

&lt;p&gt;I hope you enjoy it!&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/getsentry/raven-js&quot;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://raven-js.readthedocs.io&quot;&gt;Documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/getsentry/raven-js/issues&quot;&gt;Report a Bug&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://getsentry.com&quot;&gt;Sentry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Reusable Django Tests</title>
   <link href="https://mattrobenolt.com/reusable-django-tests/"/>
   <updated>2013-01-21T00:00:00+00:00</updated>
   <id>https://mattrobenolt.com/reusable-django-tests</id>
   <content type="html">&lt;h1 id=&quot;reusable-django-tests&quot;&gt;Reusable Django Tests&lt;/h1&gt;
&lt;p&gt;First of all, I think that testing should be accessible to everyone and should be simple enough to just “plug in” some automated tests for common patterns.&lt;/p&gt;

&lt;p&gt;Django does a pretty awesome job at encompassing applications. An application may be a blog, or a voting system, or one of many other components that require minimal configuration. These applications lower the barrier to writing larger systems.&lt;/p&gt;

&lt;p&gt;These applications come from the idea that a lot of these pieces share the same basic pieces across different projects, e.g. everyone’s tagging system is going to support the same core necessities.&lt;/p&gt;

&lt;p&gt;What if we were able to identify common testing patterns and were able to generate tests that automatically introspect and make assertions about our app for us? Then we could just &lt;em&gt;install&lt;/em&gt; a new application, apply some basic configuration, and boom! Instant tests without needing to actually write them yourself.&lt;/p&gt;

&lt;p&gt;I want to start tackling this problem and begin identifying patterns that can be extrapolated out into their own suite that is just installed and ready to go.&lt;/p&gt;

&lt;h2 id=&quot;introducing-proofread&quot;&gt;Introducing: &lt;a href=&quot;https://github.com/mattrobenolt/proofread&quot;&gt;Proofread&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My first attempt at a solution to this is a project I’ve called &lt;strong&gt;&lt;a href=&quot;https://github.com/mattrobenolt/proofread&quot;&gt;proofread&lt;/a&gt;&lt;/strong&gt;. &lt;a href=&quot;https://github.com/mattrobenolt/proofread&quot;&gt;Proofread&lt;/a&gt; tests the very basics of any web application: the public endpoints.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/mattrobenolt/proofread&quot;&gt;Proofread&lt;/a&gt; is simply configured in your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;settings.py&lt;/code&gt; to make requests to each of the endpoints on your app, and check that they respond with correct status codes.&lt;/p&gt;

&lt;h3 id=&quot;what-makes-proofread-awesome&quot;&gt;What makes &lt;a href=&quot;https://github.com/mattrobenolt/proofread&quot;&gt;Proofread&lt;/a&gt; awesome?&lt;/h3&gt;
&lt;p&gt;Well, anyone can use it, whether you’ve ever written a test before or not, and take advantage of some immediate features.&lt;/p&gt;

&lt;p&gt;In my experience, I tend to write a quick layer of tests that I’ve called a “smoke screen” check. This smoke screen would just make sure that the application worked in the most basic sense.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does making a request for the home page succeed?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That simple question can usually catch accidental &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SyntaxError&lt;/code&gt;s or missing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import&lt;/code&gt; statements. Too often have I see someone do a really quick fix and forget to import the file needed resulting in someone else cleaning up the broken commit.&lt;/p&gt;

&lt;h3 id=&quot;whats-next&quot;&gt;What’s next?&lt;/h3&gt;
&lt;p&gt;I’m going to be researching and experimenting with automating some tests for other common aspects of Django. I think my next attempt is going to be introspecting Forms and automating a test suite for validation.&lt;/p&gt;

&lt;p&gt;I’d love to hear thoughts and opinions on this topic!&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/mattrobenolt/proofread&quot;&gt;https://github.com/mattrobenolt/proofread&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Handle X-Forwarded-Port Header in Django</title>
   <link href="https://mattrobenolt.com/handle-x-forwarded-port-header-in-django/"/>
   <updated>2013-01-02T00:00:00+00:00</updated>
   <id>https://mattrobenolt.com/handle-x-forwarded-port-header-in-django</id>
   <content type="html">&lt;h1 id=&quot;handle-x-forwarded-port-header-in-django&quot;&gt;Handle &lt;nobr&gt;X-Forwarded-Port&lt;/nobr&gt; Header in Django&lt;/h1&gt;
&lt;p&gt;When running on a non-standard port, and behind a load balancer/proxy, it has become “standard”&lt;sup&gt;&lt;a href=&quot;#footnote-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt; to forward along a header called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X-Forwarded-Port&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This header is very similar to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X-Forwarded-Host&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X-Forwarded-Proto&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X-Forwarded-For&lt;/code&gt; in the sense that it’s forwarding relevent information about the originating request and telling your backend to ignore the values it’s aware of.&lt;/p&gt;

&lt;p&gt;In this case, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X-Forwarded-Port&lt;/code&gt; is not supported by Django natively, and the easiest way to handle it is through a simple middleware:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;XForwardedPort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process_request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;META&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'SERVER_PORT'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;META&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'HTTP_X_FORWARDED_PORT'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;KeyError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will allow urls to be properly reversed with the correct port as you’d expect.&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://gist.github.com/4439597&quot;&gt;https://gist.github.com/4439597&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;footnotes&quot;&gt;Footnotes&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a id=&quot;footnote-1&quot;&gt;&lt;/a&gt;&lt;small&gt;&lt;sup&gt;[1]&lt;/sup&gt; I use quotes because nobody has a fucking clue what’s really going on with this shit. There isn’t a standard, just an idea that a few people started implementing.&lt;/small&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>American Express iOS6 Passbook Security Flaw</title>
   <link href="https://mattrobenolt.com/american-express-ios6-passbook-security-flaw/"/>
   <updated>2012-09-28T00:00:00+00:00</updated>
   <id>https://mattrobenolt.com/american-express-ios6-passbook-security-flaw</id>
   <content type="html">&lt;h1 id=&quot;american-express-ios6-passbook-security-flaw&quot;&gt;American Express iOS6 Passbook Security Flaw&lt;/h1&gt;
&lt;p&gt;This morning, American Express announced that you are able to bring in your card into Passbook for iOS6 via Twitter.&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p&gt;Upgrading to &lt;a href=&quot;https://twitter.com/search/%23iOS6&quot;&gt;#iOS6&lt;/a&gt;? Add our Apple &lt;a href=&quot;https://twitter.com/search/%23Passbook&quot;&gt;#Passbook&lt;/a&gt; Pass using Safari for auto acct notifications + more &lt;a href=&quot;http://t.co/fzXm5QkX&quot; title=&quot;http://aexp.co/vn0&quot;&gt;aexp.co/vn0&lt;/a&gt; &lt;a href=&quot;http://t.co/jNu3XXHV&quot; title=&quot;http://bit.ly/Uy5MmR&quot;&gt;bit.ly/Uy5MmR&lt;/a&gt;&lt;/p&gt;&amp;mdash; American Express (@AmericanExpress) &lt;a href=&quot;https://twitter.com/AmericanExpress/status/251662955488374785&quot; data-datetime=&quot;2012-09-28T12:41:38+00:00&quot;&gt;September 28, 2012&lt;/a&gt;&lt;/blockquote&gt;
&lt;script src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;p&gt;Immediately, I try it out. Awesome.&lt;/p&gt;

&lt;p&gt;I open up Passbook, and see my balance and a list of recent transactions. Awesome again.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/U7jMm.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;https://i.imgur.com/wWnac.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then I realized what I had to do to get this Passbook file which exposes some relatively sensitive account information.&lt;/p&gt;

&lt;p&gt;The link that Amex posted is just a form, that asks simply for first name, last name, email address, credit card number, and CID. All information that anyone who has ever touched my physical card had access to.&lt;/p&gt;

&lt;p&gt;You enter in the information, and you’re giving a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.pkpass&lt;/code&gt; file, which is really just a fancy name for a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zip&lt;/code&gt; file. Extract it, and inside you’ll find a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pass.json&lt;/code&gt; file, which looks something like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;authenticationToken&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;generic&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;recentActv&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;RECENT ACTIVITY&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;textAlignment&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;PKTextAlignmentNatural&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;
        &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;primaryFields&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Matthew R.&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;
        &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;secondaryFields&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;outstandin&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Outstanding Balance&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;textAlignment&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;PKTextAlignmentLeft&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;$...&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;organizationName&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;American Express&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;passTypeIdentifier&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;pass.com.americanexpressdigitalpartners&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;serialNumber&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;teamIdentifier&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;webServiceURL&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;https://americanexpressdigitalpartners.com/pass&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;So, without entering any password or logging into my account, I can generate a list of recent transactions and an account balance.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And last, from my understanding of how Passbook works, is that new transactions are pushed to my device. So any future transactions will be updated in semi-realtime.&lt;/p&gt;

&lt;p&gt;American Express, this is awesome and all, but &lt;em&gt;PLEASE&lt;/em&gt; secure this page inside my account page after I’ve logged in, or add it to your iOS apps directly.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Django ORM & Subqueries</title>
   <link href="https://mattrobenolt.com/the-django-orm-and-subqueries/"/>
   <updated>2012-09-26T00:00:00+00:00</updated>
   <id>https://mattrobenolt.com/the-django-orm-and-subqueries</id>
   <content type="html">&lt;h1 id=&quot;the-django-orm--subqueries&quot;&gt;The Django ORM &amp;amp; Subqueries&lt;/h1&gt;
&lt;p&gt;&lt;small&gt;Note: At the time of writing, Django is at v1.4.1&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;So what actually happens when you have a Django query like the following?&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;venues&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Venue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;city__in&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Django is smart enough to know that you want to use the results from the first &lt;em&gt;unevaluated&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;QuerySet&lt;/code&gt; as the input for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__in&lt;/code&gt; clause, and in turn, generates a subquery. The raw query generated is something like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sql&quot; data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt;   &lt;span class=&quot;nv&quot;&gt;&quot;venue&quot;&lt;/span&gt; 
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;&quot;venue&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;&quot;city_id&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;U0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;&quot;id&quot;&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;&quot;city&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;U0&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Awesome. Django saved us an extra round trip by inlining the query instead of evaluating the first query separately.&lt;/p&gt;

&lt;h2 id=&quot;whats-wrong&quot;&gt;What’s wrong?&lt;/h2&gt;
&lt;p&gt;In this scenario, nothing at all. We’ve saved a round trip to the database, all is good. Let’s throw caching into the mix.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'cities'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'cities'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;venues&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Venue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;city__in&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In this scenario, we want to cache the entire list of cities. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;City&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;QuerySet&lt;/code&gt; gets cached for us like we expect, but when Django gets to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;filter()&lt;/code&gt;, it sees that you’re passing it a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;QuerySet&lt;/code&gt; and generates a subquery again. We’ve effective cached nothing because the exact same query is being run.&lt;/p&gt;

&lt;p&gt;This also applies when you want to use the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__in&lt;/code&gt; across multiple filters.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;venues&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Venue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;city__in&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UserAccount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;city__in&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Again, the exact same subquery is repeated across both queries.&lt;/p&gt;

&lt;h2 id=&quot;well-how-can-we-fix-this&quot;&gt;Well, how can we fix this?&lt;/h2&gt;
&lt;p&gt;The reason why Django is doing this is solely because the argument passed into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;filter()&lt;/code&gt; is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;QuerySet&lt;/code&gt;. If we just pass a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;list&lt;/code&gt;, Django will use an array of ids inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IN&lt;/code&gt; SQL.&lt;/p&gt;

&lt;p&gt;Let’s look at an improved version with caching.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'cities'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Force query evaluation
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'cities'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;venues&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Venue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;city__in&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The only thing that has changed is forcing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;QuerySet&lt;/code&gt; to be evaluated by converting it to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;list&lt;/code&gt;. Now, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cities&lt;/code&gt; is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;list&lt;/code&gt;, so Django won’t try to perform a subquery anymore. This could be simplified to just caching the primary keys as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;list&lt;/code&gt; as well, depending on what you’re trying to achieve.&lt;/p&gt;

&lt;p&gt;The resulting SQL will be something like:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sql&quot; data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt;   &lt;span class=&quot;nv&quot;&gt;&quot;venue&quot;&lt;/span&gt; 
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;&quot;venue&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;&quot;city_id&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;one-more-gotcha&quot;&gt;One more gotcha!&lt;/h2&gt;
&lt;p&gt;We all know that Django’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;QuerySet&lt;/code&gt;s are lazy, right? No query is actually performed until the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;QuerySet&lt;/code&gt; is iterated over. Once a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;QuerySet&lt;/code&gt; has been iterated over, it won’t query again for the results. The results get cached into an internal &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_results_cache&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;At the moment, Django is not smart enough to detect that a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;QuerySet&lt;/code&gt; has already been evaluated before generating a subquery, effectively causing the query to be run again when we already know the results.&lt;/p&gt;

&lt;p&gt;Picture this scenario:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;city&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# QuerySet cache is filled
# ... do something awesome ...
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;venues&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Venue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;city__in&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Since we’ve already evaluated the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;QuerySet&lt;/code&gt; before passing it to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__in&lt;/code&gt; clause, it’d be smart to just use the ids that we’ve already calculated from before, but it doesn’t. So pay attention and be careful.&lt;/p&gt;

&lt;p&gt;I’ve submitted a patch to Django core to try and get that behavior fixed:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/django/django/pull/396&quot;&gt;https://github.com/django/django/pull/396&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://code.djangoproject.com/ticket/19029&quot;&gt;https://code.djangoproject.com/ticket/19029&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Making shit is hard.</title>
   <link href="https://mattrobenolt.com/making-shit-is-hard/"/>
   <updated>2012-09-19T00:00:00+00:00</updated>
   <id>https://mattrobenolt.com/making-shit-is-hard</id>
   <content type="html">&lt;h1 id=&quot;making-shit-is-hard&quot;&gt;Making shit is hard.&lt;/h1&gt;
&lt;p&gt;I procrastinate a lot.&lt;/p&gt;

&lt;p&gt;I find it very difficult to commit to doing work for myself. It’s very easy to get wrapped up in doing work for other people, and it’s just so easy to say, &lt;em&gt;“Eh, I’ll get around to it,”&lt;/em&gt; when it comes to personal projects.&lt;/p&gt;

&lt;p&gt;A blog has always been at the bottom of my TODO list. I’ve had elaborate, complicated ideas for things I wanted to make custom that end up being so monstorous, that it gets in the way of what my main goal is: write some shit and have people read it.&lt;/p&gt;

&lt;p&gt;I hope to share some of my experiences as a software engineer, and help a few people along the way.&lt;/p&gt;

&lt;p&gt;This blog is currently being built with &lt;a href=&quot;https://github.com/mojombo/jekyll&quot;&gt;Jekyll&lt;/a&gt;, and hosted on &lt;a href=&quot;https://github.com/mattrobenolt/mattrobenolt.github.com&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hopefully this won’t be as hard as I’ve convinced myself it would be.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/RJ4fdKS.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content>
 </entry>
 
 
</feed>
