<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>scompt.com &#187; django</title>
	<atom:link href="http://scompt.com/blog/archives/tag/django/feed/" rel="self" type="application/rss+xml" />
	<link>http://scompt.com</link>
	<description>The website of Edward Dale</description>
	<lastBuildDate>Sun, 04 Sep 2011 15:54:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Using Django&#8217;s FormPreview with @login_required</title>
		<link>http://scompt.com/blog/archives/2007/11/07/using-djangos-formpreview-with-login_required</link>
		<comments>http://scompt.com/blog/archives/2007/11/07/using-djangos-formpreview-with-login_required#comments</comments>
		<pubDate>Wed, 07 Nov 2007 18:25:56 +0000</pubDate>
		<dc:creator>scompt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://scompt.com/archives/2007/11/07/using-djangos-formpreview-with-login_required</guid>
		<description><![CDATA[As part of Django&#8217;s &#8216;batteries included&#8217; philosophy, it comes with the FormPreview class to make it easy to automate this workflow: “Display an HTML form, force a preview, then do something with the submission.” Also provided is the @login_required decorator which makes it easy and obvious to mark functions as requiring a logged-in user. Both [...]]]></description>
			<content:encoded><![CDATA[<p>As part of Django&#8217;s &#8216;batteries included&#8217; philosophy, it comes with the <a href="http://www.djangoproject.com/documentation/form_preview/"><code>FormPreview</code> class</a> to make it easy to automate this workflow: “Display an HTML form, force a preview, then do something with the submission.”  Also provided is the <a href="http://www.djangoproject.com/documentation/authentication/#the-login-required-decorator"><code>@login_required</code></a> decorator which makes it easy and obvious to mark functions as requiring a logged-in user.  Both these features are awesome by themselves, but wouldn&#8217;t it be great to combine them and observe how much the awesomeness increases?  <span id="more-129"></span></p>
<h2><code>FormPreview</code> Review</h2>
<p>First of all, let&#8217;s review how to use the <code>FormPreview</code> class.  The general procedure is:</p>
<ol>
<li>Write a <a href="http://www.djangoproject.com/documentation/newforms/">newforms</a> Form class that models the form you want to present the user. (<code>MessageForm</code>)</li>
<li>Extend <code>FormPreview</code> and override the <code>done</code> method to provide a behavior for what happens once the user previews and submits the form. (<code>MessageFormPreview</code>)</li>
<li>Create an instance of your FormPreview and use it as the view callback in your URL configuration (<code>(r'^message/$', MessageFormPreview(MessageForm))</code>)</li>
</ol>
<p>These steps should leave us with code similar to that below and a submission form <em>with preview</em> at <code>/message/</code>.</p>
<p><code>
<pre name="code" class="python"># forms.py
from django import newforms as forms
from django.contrib.formtools.preview import FormPreview

class MessageForm(forms.Form):
    message = forms.CharField()

class MessageFormPreview(FormPreview):
    def done(self, request, cleaned_data):
        # Do something with the cleaned_data, then redirect
        # to a "success" page.
        return HttpResponseRedirect('/form/success')

# urls.py
from django.conf.urls.defaults import *

urlpatterns = patterns('', url(r'^message/$', MessageFormPreview(MessageForm)) )</pre>
<p></code></p>
<h2>The Goal</h2>
<p>The goal of this article is to <em>easily</em> secure this form preview behind the <code>@login_required</code> decorator.  Ideally, we want to make a minimum amount of changes.  Here are our requirements:</p>
<ol>
<li>Don&#8217;t make any changes to <code>MessageForm</code> or <code>MessagePreviewForm</code>.</li>
<li>No addition functions</li>
</ol>
<h2>1st try: Decorated wrapper function</h2>
<p>Unfortunately, the current <code>@login_required</code> decorator in Django trunk (revision 6652 as of this writing) doesn&#8217;t work with bound methods (&cong; instance methods).  Because of this, we&#8217;re left with only one way to do what we want, which violates the second requirement above.  The gist of the technique is that we add a wrapper view function <code>preview</code> which only returns the <code>FormPreview</code> class.  We then add the decorator to this new method.  Here&#8217;s what the code looks like:</p>
<p><code>
<pre name="code" class="python"># views.py
from django.contrib.auth.decorators import login_required

@login_required
def preview(request):
	return MessageFormPreview(MessageForm)

# urls.py
from django.conf.urls.defaults import *

urlpatterns = patterns('', url(r'^message/$', 'views.preview') )</pre>
<p></code></p>
<p>Requirement 1 is fulfilled because we haven&#8217;t made any changes to the <code>forms.py</code>.  However, requirement 2 isn&#8217;t fulfilled because we had to add the <code>preview</code> function.</p>
<h2>Patching the <code>@login_required</code> decorator</h2>
<p>The next couple solutions require a patch to allow the <code>@login_required</code> decorator to work with bound methods.  The <a href="http://code.djangoproject.com/attachment/ticket/4376/django.contrib.auth.decorators.4.diff">patch</a> is attached to ticket <a href="http://code.djangoproject.com/ticket/4376">#4376</a> in the Django trac system.  Hopefully, it will end up in the trunk sometime soon.  Go ahead and grab it and apply it to your Django install and then we&#8217;ll continue.  &#8230; &#8230; Done?  Let&#8217;s go.</p>
<h2>2nd try: Overriding <code>__call__</code></h2>
<p>You might have noticed above that we used a class (<code>FormPreview</code>) as the view function.  This works because the when the view function is executed, it calls the <code>__call__</code> instance method of <code>FormPreview</code>.  This is the method, then, that we want to decorate.  We can accomplish this by overriding it and adding the decorator to the overridden method.  This is the code we end up with:</p>
<p><code>
<pre name="code" class="python"># forms.py
from django import newforms as forms
from django.contrib.formtools.preview import FormPreview
from django.contrib.auth.decorators import login_required

class MessageForm(forms.Form):
    message = forms.CharField()

class MessageFormPreview(FormPreview):
	@login_required
	def __call__(self, request, *args, **kwargs):
	    return super(MessageFormPreview, self).__call__(request, args, kwargs)

    def done(self, request, cleaned_data):
        # Do something with the cleaned_data, then redirect
        # to a "success" page.
        return HttpResponseRedirect('/form/success')

# urls.py
from django.conf.urls.defaults import *

urlpatterns = patterns('', url(r'^message/$', MessageFormPreview(MessageForm)))</pre>
<p></code></p>
<p>You should notice immediately that we&#8217;ve violated both of the requirements that we set for ourselves.  There&#8217;s a new function (the overridden <code>__call__</code>) and we added something to the <code>MessageFormPreview</code> class, which now limits its use to &#8220;login required&#8221; situations only.</p>
<h2>3rd (and final) try: Decorate in the URLConf</h2>
<p>This final and best solution didn&#8217;t come to me until I saw <a href="http://www.b-list.org/weblog/2007/nov/06/urlconf/">this post</a> by <a href="http://www.b-list.org">James Bennett</a> (who coincidentally went to college in my <a href="http://en.wikipedia.org/wiki/Roanoke%2C_Virginia">hometown</a>).  Instead of decorating the instance method in place as we did in try 2, we decorate it at the point where it is used in the <code>urls.py</code> file.  This yields the finished code below.</p>
<p><code>
<pre name="code" class="python"># forms.py
from django import newforms as forms
from django.contrib.formtools.preview import FormPreview

class MessageForm(forms.Form):
    message = forms.CharField()

class MessageFormPreview(FormPreview):
    def done(self, request, cleaned_data):
        # Do something with the cleaned_data, then redirect
        # to a "success" page.
        return HttpResponseRedirect('/form/success')

# urls.py
from django.conf.urls.defaults import *
from django.contrib.auth.decorators import login_required

urlpatterns = patterns('', url(r'^message/$', login_required(MessageFormPreview(MessageForm))))</pre>
<p></code> </p>
<p>That good feeling you have in your heart is both of our requirements being satisfied.  We have made no changes to the <code>Form</code> or <code>FormPreview</code> classes and we have added no functions.  The only downside is that the patch for issue #4376 has not yet applied to the Django trunk.</p>
]]></content:encoded>
			<wfw:commentRss>http://scompt.com/blog/archives/2007/11/07/using-djangos-formpreview-with-login_required/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bug patches for django-voting and django-tagging</title>
		<link>http://scompt.com/blog/archives/2007/11/06/bug-patches-for-django-voting-and-django-tagging</link>
		<comments>http://scompt.com/blog/archives/2007/11/06/bug-patches-for-django-voting-and-django-tagging#comments</comments>
		<pubDate>Tue, 06 Nov 2007 11:46:16 +0000</pubDate>
		<dc:creator>scompt</dc:creator>
				<category><![CDATA[django]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://scompt.com/archives/2007/11/06/bug-patches-for-django-voting-and-django-tagging</guid>
		<description><![CDATA[As part of my top-secret Django project, I&#8217;ve enlisted the help of the django-voting and django-tagging packages to provide rating and tagging, respectively, to my models. These work wonders and serve their purpose to a T, however, I&#8217;ve come across a couple small bugs that I wanted to document here, in addition to the bug [...]]]></description>
			<content:encoded><![CDATA[<p>As part of my top-secret <a href="http://www.djangoproject.com">Django</a> project, I&#8217;ve enlisted the help of the <a href="http://code.google.com/p/django-voting/">django-voting</a> and <a href="http://code.google.com/p/django-tagging/">django-tagging</a> packages to provide rating and tagging, respectively, to my models.  These work wonders and serve their purpose to a T, however, I&#8217;ve come across a couple small bugs that I wanted to document here, in addition to the bug reports I&#8217;ve posted.</p>
<p><span id="more-128"></span></p>
<h2>django-voting get_scores_in_bulk breaks when objects is empty</h2>
<p>The <code>get_scores_in_bulk</code> method is provided to, surprisingly, retrieve the scores from a group of objects in bulk.  It&#8217;s passed the <code>object_list</code> that you get from Django&#8217;s generic views.  If you have the <code>allow_empty</code> parameter set on the generic view, then this variable may be empty.  The <a href="http://code.google.com/p/django-voting/issues/detail?id=8">bug</a> is that the <code>get_scores_in_bulk</code> method assumes that there&#8217;s at least 1 object in the list, causing an <code>IndexError</code> if that&#8217;s not true.  The patch linked below adds a check for this condition and causes everything to work.</p>
<h3><a href="http://code.google.com/p/django-voting/issues/detail?id=8">Bug Report</a>, <a href="http://code.google.com/p/django-voting/issues/attachment?aid=-7278341058987175862&#038;name=get_scores_in_bulk.patch">Patch</a></h3>
<h2>django-tagging allow_empty not supported in tagged_object_list</h2>
<p>The <code>allow_empty</code> parameter is listed as being supported in the package&#8217;s overview.txt, however, it has no effect.  Just like in Django <a href="http://www.djangoproject.com/documentation/generic_views">generic views</a>, the parameter, when set to True shows the template even when there are no objects being shown.  In my case, I wanted to show the user some other options instead of sending them a 404 error.</p>
<p>The <a href="http://code.google.com/p/django-tagging/issues/detail?id=76">bug</a> is that the <code>allow_empty</code> parameter isn&#8217;t taken into consideration at all.  The patch linked below changes the code to check <code>allow_empty</code> before raising a 404 error.  The 404 now only happens if <code>allow_empty</code> is not present or false.</p>
<h3><a href="http://code.google.com/p/django-tagging/issues/detail?id=76">Bug Report</a>, <a href="http://code.google.com/p/django-tagging/issues/attachment?aid=7039856076942437927&#038;name=allow_empty.patch">Patch</a></h3>
<p>[update: The django-voting bug has been <a href="http://code.google.com/p/django-voting/issues/detail?id=8#c1">patched</a> and now the trunk is good to go!]</p>
]]></content:encoded>
			<wfw:commentRss>http://scompt.com/blog/archives/2007/11/06/bug-patches-for-django-voting-and-django-tagging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multiple File Uploads in Django</title>
		<link>http://scompt.com/blog/archives/2007/11/03/multiple-file-uploads-in-django</link>
		<comments>http://scompt.com/blog/archives/2007/11/03/multiple-file-uploads-in-django#comments</comments>
		<pubDate>Sat, 03 Nov 2007 14:56:58 +0000</pubDate>
		<dc:creator>scompt</dc:creator>
				<category><![CDATA[django]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://scompt.com/archives/2007/11/03/multiple-file-uploads-in-django</guid>
		<description><![CDATA[As part of yet-to-be-announced project, I&#8217;m working with Django. After only a couple days, I&#8217;ve been able to produce some pretty cool results. One of the requirements that I have is that a user be able to upload a bunch of files when editing a form. Using Django&#8217;s newforms package, I was able to quickly [...]]]></description>
			<content:encoded><![CDATA[<p>As part of yet-to-be-announced project, I&#8217;m working with <a href="http://www.djangoproject.com">Django</a>.  After only a couple days, I&#8217;ve been able to produce some pretty cool results.  One of the requirements that I have is that a user be able to upload a bunch of files when editing a form.  Using Django&#8217;s <a href="http://www.djangoproject.com/documentation/newforms">newforms</a> package, I was able to quickly add the ability to upload 1 file, but I wanted the user to be able to upload as many as they wanted.</p>
<p><span id="more-127"></span></p>
<p>The solution I came up with was a custom widget (<code>MultiFileInput</code>) and field (<code>MultiFileField</code>) that allows the developer to specify the number of file input boxes to initially show.  Also, if desired, the user can be given the option to add (using Javascript) additional file input boxes.  All the uploaded files are then validated and returned as <code>UploadedFile</code> objects, just like the <code>FileField</code> included with Django.</p>
<p>The <a href='/wordpress/wp-content/uploads/2007/11/multifile.py' title='MultiFile widget and field'>MultiFile widget and field</a> are available, as are some <a href='/wordpress/wp-content/uploads/2007/11/tests.py' title='MultiFile tests'>tests</a> that should explain it&#8217;s usage.  All of the code is in the Public Domain.  If you have any questions or know a better way to do it, please leave a comment!</p>
]]></content:encoded>
			<wfw:commentRss>http://scompt.com/blog/archives/2007/11/03/multiple-file-uploads-in-django/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

