<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>On the other hand</title>
        <link>http://joshourisman.com</link>
        <description>A blog by Josh Ourisman.</description>
        <language>en-us</language>
        <lastBuildDate>Thu, 29 Mar 2012 04:55:54 -0500</lastBuildDate>
        
        <item>
            <title>Hosting with GitHub Pages</title>
            <link>2012/3/28/hosting-with-github-pages/</link>
            <description><p>It occurred to me that having transitioned my blog to be a generated static site, I was paying Rackspace ~$11 to simply host static files. (And for me to have the pleasure of managing a server in the process!) This struck me as stupid, for what are probably pretty obvious reasons. So, I've made another change to my blog hosting. I'm now using <a href="http://pages.github.com/">GitHub Pages</a>. Thanks to <a href="https://dnsimple.com/">DNSimple</a> it was drop-dead easy to change my DNS settings appropriately as well.</p> <p>I've still got one more site hosted on my Rackspace CloudServer that I need to figure out what to do with. It's basically just an image server that I'm holding onto for historical reasons (there are still various sites out there that are linking to it), so I may just throw that on GitHub pages as well (it's less than 40 MB of images, so I don't feel too bad about it), though I would much rather have a solution where I could point the domain name at my <a href="http://dropbox.com">Dropbox</a> public folder for that sort of thing. Anyone know of a way to do that? I can't just CNAME the domain to dl.dropbox.com, because that would break the existing links, instead I need it to rewrite the URL to include the path to my public folder. It would be super easy to do with Nginx, but that would require me to run and manage a server, and the whole point of all this is to not have to do such things any more. Hopefully I'll be able to come up with a solution to that...</p> <p>For all my non-static sites (including whatever personal and side-projects I might work on) I've been really, really happy with <a href="http://www.heroku.com/">Heroku</a>. If you haven't used the service I highly recommend checking them out. Hopefully I'll find the time to blog about it in more depth in the future. Suffice it to say, I will be attempting to use Heroku for pretty much every project I work on. Undoubtedly there will be some cases where it becomes necessary to manage (virtual) servers on RackSpace or EC2, but I think that's going to quickly become a small minority of cases.</p> <p>Anyway, the serving landscape has been changing with remarkable speed lately, and I'm sure it will only continue to do so. The net result is that my life is much easier, and my hosting costs much lower. Vive la (hosting) révolution!</p></description>
            <pubDate>Wed, 28 Mar 2012 06:06:10 -0500</pubDate>
            <guid>2012/3/28/hosting-with-github-pages/ </guid>
        </item>
        
        <item>
            <title>Now in syndication!</title>
            <link>2012/2/26/now-in-syndication/</link>
            <description><p>Well, I should now have a working RSS feed again. Unfortunately, I don't actually know for sure whether or not this is the case due to some complications with FeedBurner. I started using FeedBurner for this blog in 2006, well before they were bought by Google, and never really got around to doing whatever things were required when that acquisition happened. As a result, my account was never properly transitioned. I attempted to do that the other day, but it would appear that not only do I not know my FeedBurner password, I don't even know my username or the email address I used to sign up for it. Everything I tried was rejected. So, I have no way of changing my settings leaving me with a choice between changing the URL of my RSS feed (an annoying solution for my subscribers), or attempting to rebuild my new, RabbitFish-based feed in-place to keep the FeedBurner feed going. I've attempted to go with the second option, and I suppose we'll know shortly how well that worked. Looking at my server logs, it appears that FeedBurner will update roughtly every 30 minutes, so it shouldn't take too long to ascertain whether or not the new feed is working properly. I guess we'll see in about 30 minutes!</p></description>
            <pubDate>Sun, 26 Feb 2012 12:33:50 -0500</pubDate>
            <guid>2012/2/26/now-in-syndication/ </guid>
        </item>
        
        <item>
            <title>This blog is now powered by RabbitFish!</title>
            <link>2012/2/10/blog-now-powered-by-rabbitfish/</link>
            <description><p>A few months ago I made some major changes to this blog. One of the obvious changes was the new design, based on <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a>, but in addition to that I also converted the blog from a <a href="http://djangoproject.com">Django</a> site to a static site. At that point, all I actually did was scrape the site to static files using wget and throw them up on the server to be hosted with <a href="http://nginx.net">Nginx</a>, but I've now taken that a step further.</p><p>For the past three months I've been working on a personal project named <a href="https://github.com/joshourisman/rabbitfish">RabbitFish</a>. It's a static site generator built on Python 3 that uses <a href="http://jinja.pocoo.org/docs/">Jinja2</a> templates and <a href="http://www.yaml.org/">YAML</a> for storing configuration and content data. This blog is now powered by RabbitFish.</p><p>Largely because of the technical constraints of the still very immature state of RabbitFish, I've also made a few changes to the structure of the blog. Probably the most obvious is that I've gotten rid of the tag cloud that used to be in the right-hand sidebar. In addition, I've actually completely removed the tag system altogether. Of course, you'll notice that all the old posts, and this one as well, still have tags, but rather than being part of an actual tagging system, they're now basically just shortcuts for searching the blog; if you click on one, you'll see that it just takes you to the Google Custom Search for my blog with that tag filled in as the search query. Additionally, I've removed pretty much any way of navigating around the blog. Taking a page from Apple, I've decided to rely solely on search for finding blog posts. To ensure that all the posts get properly indexed, of course, I've also added a page that simply <a href="/all.html">lists all the blog posts</a>. (It's also linked to at the bottom of the index page.) Most of my traffic was organic search hits anyway, so I don't really see this causing any problems.</p><p>The one thing that I still have left to do is get syndication set up. Currently, the feed for everything prior to this post is still available thanks to FeedBurner, but I still need to set up a new, live feed to get new posts in there. Fortunately, that will be as easy as setting up a new ListPage in RabbitFish, and writing a template to build the appropriate XML file. I'll probably get that done this weekend.</p><p>Since I was already using <a href="http://disqus.com/">Disqus</a> for comments, all the old comments are already here and new comments shouldn't be a problem. I'm realy interested to hear what people think about RabbitFish, as well as the minimal interface I'm exposing for the blog now.</p><p>RabbitFish: <a href="https://github.com/joshourisman/rabbitfish">https://github.com/joshourisman/rabbitfish</a></p></description>
            <pubDate>Fri, 10 Feb 2012 03:30:00 -0500</pubDate>
            <guid>2012/2/10/blog-now-powered-by-rabbitfish/ </guid>
        </item>
        
        <item>
            <title>Adamanteus 0.5 released, now with more PostgreSQL!</title>
            <link>2010/6/5/adamanteus-05-released-now-more-postgresql/</link>
            <description>I've now finally gotten around to adding PostgreSQL support to <a href="http://bit.ly/bhEhPj">Adamanteus</a>! It wasn't really difficult, just hard to find time to do with everything that's been going on lately (quite busy at work and with the new house). The usage of Adamanteus hasn't changed at all, now you can just specify 'postgres' as your backend rather than just 'mongodb' or 'mysql'.

There is one slight caveat, however: the pg_dump utility does not allow you to provide a password non-interactively. For the time being, at least, that means that if you're using Adamanteus to back up a PostgreSQL database you can't specify a password (it will throw an exception if you do). The solution to this is to either 1) set up a read-only passwordless user for running backups, or 2) set up a .pgpass file on the machine from which you intend to run your backups (documentation <a href="http://bit.ly/91pFXF">here</a>). I recommend the .pgpass option, it's quick and easy.

Adamanteus 0.5 is available from both <a href="http://bit.ly/bhEhPj">bitbucket</a> and <a href="http://bit.ly/c6p0F0">PyPi</a>.</description>
            <pubDate>Sat, 05 Jun 2010 11:31:22 -0500</pubDate>
            <guid>2010/6/5/adamanteus-05-released-now-more-postgresql/ </guid>
        </item>
        
        <item>
            <title>Adamanteus: versioned backups of databases using Python and Mercurial</title>
            <link>2010/3/26/adamanteus-versioned-database-backups/</link>
            <description><p>Backing up databases is one of those things that I've always felt could be done in a better way. Traditionally I've done it with a simple shell script that used mysqldump or pg_dump to dump my database to an SQL file named using a timestamp, compress it, and maybe scp it off to some remote server for redundancy. This approach works just fine, except that I recently took a look at my backup directory for a project using that setup only to discover that there were nearly 5000 backup files taking up 11 GB (and this is using bzip2 to compress them!). Obviously not an optimal situation, especially considering that really very little changes from backup to backup, and it's quite possible that nothing changes at all for some of them. It simply makes no sense to store an entire dump of your database every single time!</p>

<p>Fortunately, this is a very familiar situation that we've got advanced tools to handle: version control systems. So I decided to write a little program to replace my shell script that would use a modern, advanced version control system to provide a much more reasonable solution. What I came up with was <a href="http://bitbucket.org/Josh/adamanteus/src/tip/adamanteus.py">Adamanteus</a>, a command line program written in Python that allows you to back up your database into a mercurial repository. It currently supports <a href="http://www.mongodb.org">MongoDB</a> and <a href="http://dev.mysql.com/">MySQL</a>, and I plan on adding <a href="http://www.postgresql.org/">PostgreSQL</a> support this weekend.</p>

<p>Using Mercurial immediately solves basically all the problems with my original approach. It stores diffs rather than full files, meaning you aren't wasting space with a lot of duplicate information. It also handles compression transparently keeping the file sizes down even for the diffs. Plus, because Mercurial is a distributed version control system it's very easy to provide redundancy by pushing and pulling to and from remote repositories. (Pushing/pulling to/from remote repositories isn't currently implemented, but that's also in my plans for this weekend.)</p>

<p>The project is far from complete, but I think it's sufficiently far developed to release as 0.1. Plans for the 1.0 release include:
<ul><li>PostgreSQL support</li><li>The ability to restore your database from a particular revision in the repository</li><li>automated cloning/pushing/pulling of the repository</li><li>Integration with Django as a management command</li></ul>
I think this is actually pretty close and it probably won't take too long for me to implement all of those, so hopefully I'll be able to push out a 1.0 release very soon. The one other issue holding up 1.0 is that I'd like to wait for MongoDB 1.5 which will bring <a href="http://www.mongodb.org/display/DOCS/Import+Export+Tools#ImportExportTools-mongoexport">mongoxport</a> functionality in line with <a href="http://www.mongodb.org/display/DOCS/Import+Export+Tools#ImportExportTools-mongodump">mongodump</a> which is what I'm currently using. The issue here is that mongodump produces binary data files which don't play quite as nice with version control and lose you the advantage of only storing diffs. Mongoexport will export JSON or CSV files, which <em>will</em> allow it to take full advantage of Mercurial, <em>but</em> until 1.5 there's no easy way to use mongoexport to dump all the collections in a database which is the default behavior for mongodump.</p>

<p>Anyway, I'm definitely looking forward to some feedback on this project, as I suspect it could be quite useful to many people. Contributions are always welcome as well!</p></description>
            <pubDate>Fri, 26 Mar 2010 05:20:09 -0500</pubDate>
            <guid>2010/3/26/adamanteus-versioned-database-backups/ </guid>
        </item>
        
        <item>
            <title>More on the massive ObamaCare Loophole</title>
            <link>2010/3/26/more-massive-obamacare-loophole/</link>
            <description><p>Since <a href="http://joshourisman.com/2010/03/23/what-does-obamacare-actually-do/">my last post</a> I've seen quite a few other people writing about exactly the same issue with ObamaCare that I saw: it actually encourages people to <em>not</em> carry health insurance. The most recent is someone's whose blog I've been reading for a while and whose opinions I generally respect: <a href="http://blogs.law.harvard.edu/philg/">Philip Greenspun</a> an <a href="http://en.wikipedia.org/wiki/Electrical_Engineering_and_Computer_Science">EECS</a> professor at MIT. He actually did the math to reveal that a family in Massachusetts making $100,000 can expect to pay around $20,000 per year on insurance. The fine for not carrying insurance, however, would only be $2,000. And, of course, the insurance carriers would be forbidden from denying them of insurance if they showed up already sick and actually in need of health care.</p>

<p>But there's more! <a href="http://econlog.econlib.org/authorbcaplan.html">Brian Caplan</a> at the <a href="http://www.econlib.org/">Library of Economics and Liberty</a> (which I don't actually know much about, but I would guess is biased in the libertarian direction from a cursory examination of the site) suggests another unexpected side-effect of ObamaCare will be that <a href="http://econlog.econlib.org/archives/2010/03/how_many_employ.html#">employers will stop offering insurance as a benefit</a>. Part of the reason it's currently so common for insurance to be an employment benefit is that the government has been encouraging this behavior since around WWII by not counting health insurance as taxable income. This, apparently, is going to change with ObamaCare.</p>

<p>This, however, I think is actually a good thing. I mentioned in my last post that I had some ideas on a different sort of reform that I've posted about elsewhere in the past; below is an outline of some ideas that I put together a couple years ago (around the time that Massachusetts was debating the inspiration for ObamaCare):</p>

<p><ul><li>Decouple health insurance from employment</li><ul><li>current system economically stupid</li><ul><li>encourages un-educated consumers</li><li>reduces consumer choice</li><li>reduces competition in the market</li></ul><li>current system unnecessarily restricts consumers</li><ul><li>people with health problems can't change jobs for fear of losing insurance</li><li>true cost of insurance is hidden from consumers</li></ul></ul><li>Make medical costs tax deductible</li><ul><li>all costs should be up to 100% tax deductible (maybe variable by income)</li><li>makes health care significantly more affordable</li><li>provides the same functional assistance as a single-payer system</li><li>doesn't encourage reliance on the system</li><li>doesn't require increased bureaucracy</li><li>encourages personal responsibility</li></ul><li>Provide low/no interest loads to cover medical costs</li><ul><li>interest rate based on need</li><li>removes problem of non-payment</li><li>allows even the uninsured to afford very expensive procedures</li><li>doesn't encourage reliance on the system</li><li>payments are tax deductible under point 2</li></ul><li>Loosen regulations on insurance industry</li><ul><li>regulations such as setting a maximum deductible hurt both sides</li><ul><li>consumers aren't allowed to decide for themselves what they need</li><li>insurers aren't allowed to innovate and find new solutions</li></ul><li>regulations reduce competition</li><ul><li>not <em>all</em> of them!</li><li>regulations provide a disincentive for new insurance companies to enter the market</li><li>the more insurance companies there are, the better for consumers</li></ul></ul></ul></p>

<p>Obviously this is still rather rough, and some of the points are clearly designed to address things that have now changed. However I think this is a decent outline of changes that could be made to healthcare that would meet the goals of <em>both</em> sides of the public/private argument. I'm sure there's tons of discussion that could be had on just about every one of my points, so perhaps I'll take the time to break each one out into a separate blog post where I can go into more detail in the future. Also, I'll try and write some more about the code I've been working on as there's some good stuff involving <a href="http://www.mongodb.org/">MongoDB</a>, <a href="http://hmarr.com/2010/feb/04/introducing-mongoengine/">MongoEngine</a>, and&mdash;of course&mdash;<a href="http://www.djangoproject.com/">Django</a>.</p></description>
            <pubDate>Fri, 26 Mar 2010 07:49:54 -0500</pubDate>
            <guid>2010/3/26/more-massive-obamacare-loophole/ </guid>
        </item>
        
        <item>
            <title>What does ObamaCare actually do?</title>
            <link>2010/3/23/what-does-obamacare-actually-do/</link>
            <description><p>I've been generally on the fence about ObamaCare&mdash;and really about the various proposals to reform healthcare in general. I do think that our system needs reform, it's just that I've been unconvinced about the specific proposals made for the form that reform should take. But now it's 'happened' (although what we have is not really healthcare reform so much as health <em>insurance</em> reform) so the question is now different: what are the implications of our new system, and where do we go from here?</p>

<p>The implications, I think, are both quite interesting and not at all what most people expect/want them to be. For example, I think the new bill will actually <em>increase</em> the number of uninsured people in America (at least in the short term), and I think it will do this via two separate mechanisms:
<ol><li>An active dumping of high-cost and/or risky customers by the insurance companies who currently cover them, and</li>
<li>People taking advantage of the new system to actually save money without sacrificing healthcare by foregoing insurance</li></ol>
But isn't the whole purpose of the reform to make both of those specific things impossible? It's certainly the <em>stated</em> purpose, at any rate. So why would I claim that the effects of this bill are going to be exactly the opposite of what we were promised they would be? Well, what does the bill actually do?</p>
<p>Let's look at the first mechanism I mentioned above: insurance companies actively dumping expensive patients (even more so than they already do, I mean). Starting in 2014 they will no longer be able to do this, they will have to cover everyone. But for the next four years they are free to continue doing so, and it makes a lot of sense that they would ramp up this practice so that they can increase revenues as much as possible in preparation for that future. In the meantime the government is offering some sort of high-risk pool of insurance for those people that can't currently get coverage, so it won't even seem like that bad of a deal: the insurance companies win by increasing revenue, Obama wins by being able to point to the vast numbers of people that are already being helped by the program, the patients win because they have health care, and the taxpayers win because... well, actually we don't so much... But that's really not so bad; it's hard to complain about people with health problems getting the help they need, even if you don't think they're getting it in the best possible way and you don't want to have to pay for it. It's the other mechanism listed above that I think is more insidious: gaming the system.</p>
<p>How and why would people game the system? Well, it's actually quite easy and straightforward: as things stand it's quite easy to get the best of both worlds: save money by not purchasing health insurance and still be able to rely on health insurance to pay for your medical expenses. The reason this work is that the 'individual mandate' of ObamaCare is toothless: <a href="http://joshourisman.com/2007/10/10/health-care/">just as in Massachusetts</a> it's cheaper to pay the fine imposed for not purchasing health insurance than it is to actually purchase that insurance. $100 per year or 1% of your income (whichever is more). That's a pretty paltry fine (though it will increase in 2014 along with the activation of the various other parts of the program). And couple that with the high-risk pools that you'll be able to buy into to get government subsidized healthcare regardless of pre-existing conditions it renders this whole change meaningless (or worse?)! Why would I pay thousands of dollars per year for insurance when I can pay much less and then, if I get sick or injured, simply buy into a plan that I legally can't be turned away from? I'd end up paying less money than I would if I actually carried insurance, but I would still get all the benefits of that insurance! As long as the fine/tax for not carrying insurance is less than the cost of actual insurance, and as long as it is required by law that you be able to buy insurance at any point regardless of your current health conditions, there is absolutely no incentive for anyone to ever purchase insurance right up until the point that they actually need it!</p>
<p>The implications of this are quite staggering: they basically undo the whole fabric of our healthcare system. Our system (even now) is based upon the idea that it's relatively cheap to pay for routine healthcare costs, but relatively expensive to pay for the bigger and rarer procedures. So we amortize those costs over time and over a large pool of people by buying into insurance plans where everyone pays in a relatively small amount and then, on the rare occasion that they need it, they're able to draw a large amount to cover larger medical expenses. But ObamaCare has undone that! Now we don't need to pay into the system (except in a barely token amount) in order to draw from it! If and once people realize this and start dumping their insurance plans, this will lead to the collapse of the insurance industry; it will simply be impossible to operate under the insurance model.</p>
<p>The result of this will be greater and greater financial obligation on the government to support the insurance industry and pay for that healthcare and therefore a greater and greater tax burden on us to pay for it until, eventually, we are all simply paying taxes into a government system that funds all our healthcare needs. Sound familiar? That's because it's a single-payer system&mdash;a monstrously constructed single-payer system built with the rotting corpses of the various insurance companies.</p>
<p>This is, of course, a worst-case scenario. In order for this two actually happen at least one of two things has to be true:
<ol><li>Our government has to be incompetent enough to not recognize and fix these problems before they overwhelm us, or</li>
<li>The intended goal of this plan was, all along, to simply set us on the path to a single-payer system</li></ol>
Neither of these options would really be all that surprising to me, frankly. I'm pretty sure our government <em>is</em> that incompetent, and I'm pretty sure that the people who initially conceived and designed this reform would prefer a single-payer system. But we'll have to wait and see what happens. Regardless, I think it's safe to say that there are really only two possible systems for health care that would be stable: a fully private system, or a single-payer system. There are benefits and disadvantages to both, and there are all manner of compromises between them that I think could actually be good (which I've written about elsewhere in the past, and should really write a post here about as well). But—as much as I hate to sound like I'm parroting those who truly are on the lunatic fringe—we really are looking at the opening salvo in a battle for single-payer healthcare in the US. Whether you think this is a bad thing or not is up to you.</p></description>
            <pubDate>Tue, 23 Mar 2010 02:25:14 -0500</pubDate>
            <guid>2010/3/23/what-does-obamacare-actually-do/ </guid>
        </item>
        
        <item>
            <title>A zsh prompt for Mercurial users</title>
            <link>2009/11/16/zsh-prompt-mercurial-users/</link>
            <description>My friend <a href="http://sebastiancelis.com/">Sebastian Celis</a> recently posted on his blog about <a href="http://sebastiancelis.com/2009/nov/16/zsh-prompt-git-users/">a zsh prompt for Git users</a>. Basically, it's a set of scripts for ZSH that allow it to display the current status of the Git repo you're currently in. Very cool stuff, but unfortunately I don't use Git (very often), and instead use Mercurial for most of my projects. So I decided to modify it to work with Mercurial.

Very little has changed from his Git version (in fact, in most files it was a simple s/git/hg/), so I'm not going to go over how it all works. If you want to know that, you should read <a href="http://sebastiancelis.com/2009/nov/16/zsh-prompt-git-users/">his original blog post</a>. Instead, I'm just going to link to my bitbucket project for it: <a href="http://bitbucket.org/Josh/mercurial-for-zsh/">Mercurial for ZSH</a>.

It is, at this point, a pretty half-assed port. There's still some work to do to fine-tune it for Mercurial, but it works. Another thing I'm interested in doing is seeing if I can get it to auto-detect what VCS is being used for the current directory and act accordingly so that it doesn't have to be limited to either Merurial or Git (which goes along nicely with another project that I'm working on and will hopefully be able to write about soon). But, half-assed or not, I think it may be useful to anyone out there using both ZSH and Mercurial (or any any VCS, if you want to fork the code again).</description>
            <pubDate>Mon, 16 Nov 2009 11:02:06 -0500</pubDate>
            <guid>2009/11/16/zsh-prompt-mercurial-users/ </guid>
        </item>
        
        <item>
            <title>Car free once again</title>
            <link>2009/11/3/car-free-once-again/</link>
            <description>After a year and five months, Jessi and I are car free once again! Yup, yesterday we sold our '06 Mazda 3 that we bought in '07 and re-entered the ranks of the urban carless. This is the second time we've been without a car, the first was right after I moved to Boston from California and sold my Camaro. That lasted for about 6 months before Jessi got a new job that was not accessible by public transit.

This time, with my new job at <a href="http://creative.discovery.com/">Discovery Creative</a>, and Jessi working from home, a car has become an unnecessary expense. A very large unnecessary expense, as a matter of fact: before taking into account gas an maintenance, owning the car was costing us around $500 per month! That's a lot of extra money that's now going to be sitting in our bank account! Of course some of it will go to <a href="http://www.zipcar.com/">Zipcar</a> rentals for the few times when we actually do need a car, and some will probably go to getting our groceries delivered by either Peapod/Giant or Safeway, but even still those added expenses should be far less than what we're saving by having no car.</description>
            <pubDate>Tue, 03 Nov 2009 03:41:45 -0500</pubDate>
            <guid>2009/11/3/car-free-once-again/ </guid>
        </item>
        
        <item>
            <title>Django admin awesomeness</title>
            <link>2009/10/15/django-admin-awesomeness/</link>
            <description>Yes, I realize that this is now my third post not related to DVCSes since I said my next post would be about DVCSes. So sue me.

I recently encountered an interesting requirement for the <a href="http://www.djangoproject.com/">Django</a> <a href="http://docs.djangoproject.com/en/dev/ref/contrib/admin/#ref-contrib-admin">admin</a>: we wanted people to normally only see (and be able to edit) objects that either they created themselves, or that the creator had assigned them to. Fortunately this is insanely easy in Django 1.1, all you have to do is override the queryset() method of the appropriate ModelAdmin like so:

<script src="http://gist.github.com/211008.js"></script>

This snippet very easily allows you to apply essentially any filter you want to the QuerySet that gets passed on to the change_list and allows you to provide an exception for super users (always a good thing!). That part was really easy and something I've done before (even in 1.0.x where the functionality is there, just not exposed). Where it got trickier was where the client also wanted the functionality to be able to view <em>all</em> the objects regardless of who created them, but still only have editing capabilities for their own objects (and only see the information available on the change_list for others).

This part was much harder, but fortunately also made very possible by the updates to ModelAdmin in the 1.1.x branch. The first thing I wanted to do was just provide a new URL and view integrated seamlessly into the admin. Again this was very simple with the new admin, and required only overriding the get_urls() method on the ModelAdmin:

<script src="http://gist.github.com/211020.js"></script>

Getting that all_objects view to return something essentially identical to the normal change_list, but with a completely different filter on the queryset, and some different display options was the real problem I had to address. Wrapping my head around the problem took some time, but fortunately even this was pretty simple once I really started to get into the flexibility of the ModelAdmin class.

Broken down to it's most basic level, what I wanted to do was return the change_list view from a Model Admin. This in itself is very simple to do, and requires very little code:

<script src="http://gist.github.com/211023.js"></script>

Once I figure that out it was pretty obvious that what I needed to do was subclass my ModelAdmin and just re-overide the relevant functions. Turns out this is really easy to do, and gives you a whole lot of flexibility. So I created a special AllItemsAdmin subclass of ThisAdmin, and overrode <em>that</em> queryset() method to return all the objects. I then had to figure out a way to get it to only display but not link to edit pages for objects that the current user doesn't own. Since I needed them to be in the queryset, this was a little trickier.

Anyone who's been working with the Django admin should know about the <a href="http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display">list_display</a> option on the ModelAdmin. What you might not know (I didn't until recently) is that no only can the list_display list contain field names and properties from the model (Actually, if you didn't know that you can provide <a href="http://docs.djangoproject.com/en/dev/topics/db/models/#id4">callable properties from your model</a>, you should check that out. It lets you do some very useful things.), you can also provide <em>callables from within your model admin</em>. So you could set your list_display to something like ['title', 'my_function'] where my_function is a method on your model admin with a definition along the lines of my_function(self, object) that can perform operations on the Django object for that row and return whatever value you want.  The normal options for model properties (such as allow_tags and short_description) work here as well. So what I was able to do with this was create a custom column for my change_list that looked at the specific object, checked the ownership properties as above, and then returned either just the name of the object, or the name of the object as a link to the regular edit page for that object. By setting list_display_links to (None,) I was able to prevent any of the fields from automatically be turned into links. Of course doing this required that method to have access to the request which it usually wouldn't, but since I was already working with a hacked up subclass of my ModelAdmin I was able to just override the __init__() to take the request object and pass that in when I instantiated it. What I ended up with was this really awesome view (if I do say so myself):

<script src="http://gist.github.com/211037.js"></script>

As you can see, this is also using another new feature in the 1.1.x admin: reversing of admin URLs. After this all I needed was a few simple changes to the change_list.html template for this model let me add a 'View all' link to go to this new view, and then the 'all' context variable being passed in as extra context simply tells it to provide a link back to the standard view otherwise.

The result of all this was a seamless integration of my custom 'view, but don't edit all' view into the Django admin.</description>
            <pubDate>Thu, 15 Oct 2009 10:30:27 -0500</pubDate>
            <guid>2009/10/15/django-admin-awesomeness/ </guid>
        </item>
        
    </channel>
</rss>