<?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/"
	>

<channel>
	<title>Dashdrum</title>
	<atom:link href="http://dashdrum.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://dashdrum.com/blog</link>
	<description>Programming Notes, Application Thoughts, and other Musings</description>
	<lastBuildDate>Fri, 17 Feb 2012 19:36:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Django Templates for the Designer</title>
		<link>http://dashdrum.com/blog/2012/02/django-templates-for-the-designer/</link>
		<comments>http://dashdrum.com/blog/2012/02/django-templates-for-the-designer/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 19:36:44 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://dashdrum.com/blog/?p=349</guid>
		<description><![CDATA[There&#8217;s no need to know Python or Django to work well with Django templates. A good understanding of the way HTML is generated will take the designer most of the way. A common shortcut in rendering a form in the &#8230; <a href="http://dashdrum.com/blog/2012/02/django-templates-for-the-designer/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s no need to know Python or Django to work well with Django templates. A good understanding of the way HTML is generated will take the designer most of the way.</p>
<p>A common shortcut in rendering a form in the template is to use <code>{{ form.as_p }}</code>.  This will include all of the included fields from the form, along with labels and errors.   A nice side effect is that changes to the fields &#8211; whether adding a new field, taking one away, or changing its format &#8211; are reflected immediately when the app is restarted without any modifications necessary for the template itself.  Here&#8217;s an example:</p>
<pre>&lt;form action="." method="post"&gt;{% csrf_token %}
{{ form.as_p }}
&lt;input type="submit" value="Save" /&gt;&lt;/form&gt;</pre>
<p>However, without an understanding of the underlying form, and possibly a related model, it can be difficult for the non-developer to predict which fields will be included. When using a basic <code>Form</code>, one just needs to check the form definition to see the list of fields.  This form is a good example:</p>
<pre>class UserSelectForm(Form):
    user = ChoiceField(required=True)
    reg_date = DateField(required=False)</pre>
<p>Just the two fields listed will be included in the generated HTML.</p>
<p>With a <code>ModelForm</code>, things get a little more complicated. Before viewing an example, let&#8217;s start with a quick set of rules:</p>
<ol>
<li>All fields from the related model will be included</li>
<li>UNLESS, the field is marked as <code>editable=False</code> in the model definition</li>
<li>The <code>fields</code> attribute in the <code>ModelForm</code>&#8216;s Meta section can be used to limit the form to a subset of the fields</li>
<li>The <code>exclude</code> attribue, also in the Meta section, is used to omit fields from the form</li>
<li>Additional fields specified in the form that are not part of the model will also be included</li>
</ol>
<p>For more information, see <a href="http://docs.djangoproject.com/en/dev/topics/forms/modelsforms/#modelform">Creating Forms from Models</a> in the Django documentation.</p>
<p>Here&#8217;s an example:</p>
<pre>class TrainingScheduleForm(ModelForm):
    class_date = DateFieldMultiFormat(required=True)
    class_time = TimeFieldMultiFormat(required=True)
    send_email = fields.BooleanField(required=False)

    class Meta:
        model = TrainingSchedule
        exclude = ('training_class',)</pre>
<p>The <code>model</code> attribute tells us to look at the TrainingSchedule model and include those fields that are editable.</p>
<pre>class TrainingSchedule(ModelBase):
    training_class = models.ForeignKey(TrainingClass,null=False,blank=False)
    class_date = models.DateField(null=False,blank=False)
    class_time = models.TimeField(null=False,blank=False)
    location = models.CharField(max_length=255,null=True,blank=True)
    campus = models.CharField(max_length=255,null=True,blank=True)
    capacity = models.IntegerField(blank=True,null=True)
    display_flag = models.BooleanField(default=True)</pre>
<p>Then, we look at the <code>exclude</code> attribute to see that the training_class field is not included. Class_date and class_time are explicitly listed only because of a need to override the default field type, but the send_email is an extra field that is not part of the model. It is included as well. So, the final list of fields in the template is:</p>
<ul>
<li>class_date</li>
<li>class_time</li>
<li>location</li>
<li>campus</li>
<li>capacity</li>
<li>display_flag</li>
<li>send_email</li>
</ul>
<p>Using the <code>{{ form.as_p }}</code> shortcut, the HTML will include this snippet:</p>
<pre>&lt;p&gt;&lt;label for="id_class_date"&gt;Class date&lt;/label&gt;&lt;input type="text" name="class_date" id="id_class_date" /&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="id_class_time"&gt;Class time&lt;/label&gt;&lt;input type="text" name="class_time" id="id_class_time" /&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="id_location"&gt;Location&lt;/label&gt;&lt;input id="id_location" type="text" name="location" maxlength="255" /&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="id_campus"&gt;Campus&lt;/label&gt;&lt;input id="id_campus" type="text" name="campus" maxlength="255" /&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="id_capacity"&gt;Capacity&lt;/label&gt;&lt;input type="text" name="capacity" id="id_capacity" /&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="id_display_flag"&gt;Display flag&lt;/label&gt;&lt;input checked="checked" type="checkbox" name="display_flag" id="id_display_flag" /&gt; &lt;/p&gt;
&lt;p&gt;&lt;label for="id_send_email"&gt;Send email:&lt;/label&gt; &lt;input type="checkbox" name="send_email" id="id_send_email" /&gt;&lt;/p&gt;</pre>
<p>Note that both the labels and fields have IDs just waiting to be styled. If there were any errors generated, those sections would also be included, with all of the ID and class goodness.</p>
<h2>Shortcomings</h2>
<p>Sometimes, the designer wants to change the order of the fields, put the errors in a different spot, assign other classes and IDs, and insert additional information in the template. In these cases, one can skip the shortcut, and specify the form pieces individually. Here is an example of a template with individual fields listed:</p>
<pre>&lt;form action="." method="post"&gt; {% csrf_token %}

&lt;div id="signup_details"&gt;

{{ form.non_field_errors }}

&lt;p&gt;{{ form.training_class.errors }}{{ form.training_class.label_tag }} {{ form.training_class }}&lt;/p&gt;
&lt;p&gt;{{ form.training_schedule.errors }}{{ form.training_schedule.label_tag }} {{ form.training_schedule }}&lt;/p&gt;

&lt;fieldset id="new_schedule"&gt;
&lt;legend&gt;Create New Schedule&lt;/legend&gt;
&lt;p&gt;{{ form.class_date.errors }}{{ form.class_date.label_tag }} {{ form.class_date }}&lt;/p&gt;
&lt;p&gt;{{ form.class_time.errors }}{{ form.class_time.label_tag }} {{ form.class_time }}&lt;/p&gt;
&lt;p&gt;{{ form.location.errors }}{{ form.location.label_tag }} {{ form.location }}&lt;/p&gt;
&lt;p&gt;{{ form.campus.errors }}{{ form.campus.label_tag }} {{ form.campus }}&lt;/p&gt;
&lt;/fieldset&gt;

&lt;/div&gt;
&lt;div id="signup_flags"&gt;
&lt;p&gt;{{ form.send_email.errors }}{{ form.send_email.label_tag }} {{ form.send_email }}&lt;/p&gt;
&lt;p&gt;{{ form.attended.errors }}{{ form.attended.label_tag }} {{ form.attended }}&lt;/p&gt;
&lt;p&gt;{{ form.exempt.errors }}{{ form.exempt.label_tag }} {{ form.exempt }}&lt;/p&gt;
&lt;/div&gt;

&lt;br clear="left" /&gt;&lt;br /&gt;

&lt;input type="submit" value="Save" /&gt;
&lt;INPUT TYPE="BUTTON" VALUE="Cancel" onClick="history.go(-1)"&gt;
&lt;/form&gt;</pre>
<p>Note a couple of things. The tag <code>{{ form.non_field_errors }}</code> is where any form level errors would be displayed. Likewise, the <code>{{ form.<em>field_name</em>.errors }}</code> tag holds the place for individual field errors.</p>
<p>Once the tags are in the form, the designer can move them around and add additional HTML &#8211; notice the use of <code>fieldset</code> above.</p>
<p>See more information on the individual tags in <a title="Working With Forms - Looping Over the Form's Fields" href="http://docs.djangoproject.com/en/dev/topics/forms/#looping-over-the-form-s-fields">Working With Forms</a>.</p>
<p>Hope this helps a few designers figure out Django templates.  Please leave any comments or questions below.</p>
]]></content:encoded>
			<wfw:commentRss>http://dashdrum.com/blog/2012/02/django-templates-for-the-designer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Better Way &#8211; Don&#8217;t!</title>
		<link>http://dashdrum.com/blog/2012/01/a-better-way-dont/</link>
		<comments>http://dashdrum.com/blog/2012/01/a-better-way-dont/#comments</comments>
		<pubDate>Sun, 29 Jan 2012 14:44:47 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[class based views]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://dashdrum.com/blog/?p=329</guid>
		<description><![CDATA[In an earlier post, I talked about using form.save(commit=False) in a class based view, and I showed a way to do it.  However, I wasn&#8217;t looking far enough back to see the real question: How can I add information not &#8230; <a href="http://dashdrum.com/blog/2012/01/a-better-way-dont/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In an <a title="Using form.save(commit=False) in a Class Based View" href="http://dashdrum.com/blog/2011/12/using-form-savecommitfalse-in-a-class-based-view/">earlier post</a>, I talked about using <code>form.save(commit=False)</code> in a class based view, and I showed a way to do it.  However, I wasn&#8217;t looking far enough back to see the real question:</p>
<p><em>How can I add information not found on the form to the object before saving?</em></p>
<p>Thanks to a reply way down in this <a title="Class-Based Generic Views (CreateView) - field exclusions and defaults" href="http://groups.google.com/group/django-users/browse_thread/thread/f8a9832dcb5e9e87">Google Groups post</a>, I found what I needed, and I kicked my self for not seeing this earlier. Since I was using the default form logic to save the object, I could send the additional value to the form.</p>
<pre>    ## Include the instance object before saving
    def form_valid(self, form):
        form.instance.institution = self.institution
        return super(EventCreateView,self).form_valid(form)</pre>
<p>I like this solution better than what I provided in the <a title="Using form.save(commit=False) in a Class Based View" href="http://dashdrum.com/blog/2011/12/using-form-savecommitfalse-in-a-class-based-view/">earlier post</a> because it is a better object oriented approach.</p>
<p>Of course, I have used the older example all over my applications, so I&#8217;ve got some refactoring to do.</p>
]]></content:encoded>
			<wfw:commentRss>http://dashdrum.com/blog/2012/01/a-better-way-dont/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Installing Oracle Client on Ubuntu 11.10</title>
		<link>http://dashdrum.com/blog/2012/01/installing-oracle-client-on-ubuntu-11-10/</link>
		<comments>http://dashdrum.com/blog/2012/01/installing-oracle-client-on-ubuntu-11-10/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 21:51:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://dashdrum.com/blog/?p=317</guid>
		<description><![CDATA[(Another post written for personal documentation) Get Software Download these three packages from Oracle for the proper operating system (32 bit for me): Instant Client Basic-Lite Instant Client SDK Instand Client SQLPlus Unzip and copy to /opt/oracle/11_2/instantclient Set LD_LIBRARY_PATH Create &#8230; <a href="http://dashdrum.com/blog/2012/01/installing-oracle-client-on-ubuntu-11-10/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img title="Oracle Logo" src="http://www.techshout.com/images/oracle-logo.gif" alt="Oracle Logo" width="150" height="150" align="right" hspace="11" vspace="11" />(Another post written for personal documentation)</p>
<h2>Get Software</h2>
<p>Download these three packages from Oracle for the proper operating system (32 bit for me):</p>
<ul>
<li>Instant Client Basic-Lite</li>
<li>Instant Client SDK</li>
<li>Instand Client SQLPlus</li>
</ul>
<p>Unzip and copy to /opt/oracle/11_2/instantclient</p>
<h2>Set LD_LIBRARY_PATH</h2>
<p>Create /etc/ld.so.conf.d/oracle_instantclient.conf:</p>
<pre>#Oracle client LD_LIBRARY_PATH setting
/opt/oracle/11_2/instantclient</pre>
<p>Update cache:</p>
<pre>sudo ldconfig -v</pre>
<h2>Symbolic Link to Library</h2>
<pre>ln -s libclntsh.so.10.1 libclntsh.so</pre>
<h2>Set ORACLE_HOME</h2>
<pre>export ORACLE_HOME=/opt/oracle/11_2/instantclient</pre>
<h2>Install Python Library</h2>
<p>The library is called cx-oracle. Use your favorite installation method. (Don&#8217;t forget about your virtual environment!)</p>
<h2>That&#8217;s It</h2>
<p>Hope I remembered everything.</p>
<h2>UPDATE</h2>
<p>Found another post that outlines the procedure maybe a little better than I did, and includes notes on setting up <code>tnsnames.ora</code>. See <a href="http://chilipuppy.blogspot.com/2008/10/purpose-im-working-on-building-python.html">Install Oracle Instant Client 11.1 and cx_Oracle 4.4 on Ubuntu 8.04 on Technoblog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://dashdrum.com/blog/2012/01/installing-oracle-client-on-ubuntu-11-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using form.save(commit=False) in a Class Based View</title>
		<link>http://dashdrum.com/blog/2011/12/using-form-savecommitfalse-in-a-class-based-view/</link>
		<comments>http://dashdrum.com/blog/2011/12/using-form-savecommitfalse-in-a-class-based-view/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 18:14:34 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[class based views]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://dashdrum.com/blog/?p=311</guid>
		<description><![CDATA[UPDATE: I found a better way to do this.  See this post. In this example, I once again hadn&#8217;t used a generic view for this create function, since I needed to add a value that is not in the form &#8230; <a href="http://dashdrum.com/blog/2011/12/using-form-savecommitfalse-in-a-class-based-view/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE: I found a better way to do this.  <a title="A Better Way – Don’t!" href="http://dashdrum.com/blog/2012/01/a-better-way-dont/">See this post</a>.</strong></p>
<p>In this example, I once again hadn&#8217;t used a generic view for this create function, since I needed to add a value that is not in the form to the new object before the save.</p>
<pre>    if form.is_valid():
        new_rec = form.save(commit=False)
        new_rec.institution = institution
        new_rec.save()
        return HttpResponseRedirect(reverse('cat_list'))</pre>
<p>The value for <code>institution</code> comes from the user&#8217;s session area. The above is the accepted pattern to add the data to the object.</p>
<h2>So how can we do this in a class based view?</h2>
<p>An override of <code>form_valid()</code> in the class will handle this case.</p>
<pre>    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.institution = self.kwargs['institution']
        self.object.save()
        return HttpResponseRedirect(self.get_success_url())</pre>
<p>(Putting the institution value in kwargs is the subject for another post. One could also use an object variable.)</p>
<p><strong>UPDATE: I found a better way to do this.  <a title="A Better Way – Don’t!" href="http://dashdrum.com/blog/2012/01/a-better-way-dont/">See this post</a>.</strong></p>
<p>The reader who just wants to know how to do this can stop here. However&#8230;.</p>
<h2>Is this the best way to do this?</h2>
<p>I&#8217;m not very skilled in the art of overriding methods, so I am a little concerned about the forward compatibility of this solution.<br />
Let&#8217;s first see the upstream definitions of this method.<br />
The method is defined in ModelFormMixin as follows:</p>
<pre>    def form_valid(self, form):
        self.object = form.save()
        return super(ModelFormMixin, self).form_valid(form)</pre>
<p>And above that we find a simpler method in FormMixin:</p>
<pre>    def form_valid(self, form):
        return HttpResponseRedirect(self.get_success_url())</pre>
<p>I like how the ModelFormMixin method is able to refer back to the original using the super function, but I don&#8217;t know how I can jump over the immediate ancestor to call back the original method. Is this possible? Does it matter?</p>
<p>I am slightly concerned that changes to the method in FormMixin that may come along in future versions may be overlooked with this solution. Sure, I have to check these things during an upgrade anyway, but I would like to perform this as &#8220;correctly&#8221; as possible.</p>
<p>Please leave your suggestions, thoughts and comments below.</p>
<p><strong>UPDATE: I found a better way to do this.  <a title="A Better Way – Don’t!" href="http://dashdrum.com/blog/2012/01/a-better-way-dont/">See this post</a>.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://dashdrum.com/blog/2011/12/using-form-savecommitfalse-in-a-class-based-view/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Class Based Views: CreateView Example</title>
		<link>http://dashdrum.com/blog/2011/11/class-based-views-createview-example/</link>
		<comments>http://dashdrum.com/blog/2011/11/class-based-views-createview-example/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 19:56:04 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[class based views]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://dashdrum.com/blog/?p=307</guid>
		<description><![CDATA[For this example I&#8217;m not starting with a generic view. That&#8217;s because the code includes support for an extra submit button &#8211; in this case &#8220;Save and Add Another&#8221;. Without it, I would have used the generic view. Before: @permission_required('calendars.add_eventtype') &#8230; <a href="http://dashdrum.com/blog/2011/11/class-based-views-createview-example/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For this example I&#8217;m not starting with a generic view.  That&#8217;s because the code includes support for an extra submit button &#8211; in this case &#8220;Save and Add Another&#8221;.  Without it, I would have used the generic view.</p>
<p>Before:</p>
<pre>

@permission_required('calendars.add_eventtype')
def create_type(request):
    evttypeform = EventTypeForm(request.POST or None)

    if evttypeform.is_valid():
        evttypeform.save()
        if '_addanother' in request.POST:
            return HttpResponseRedirect(reverse('create_type'))

        return HttpResponseRedirect(reverse('list_type'))

    return render_to_response('eventtype_form.html',
                              {'form' : evttypeform, 'create_form': True,
                    'calendar_menu': CalendarName.menu.all(),   },
                               context_instance=RequestContext(request))</pre>
<p>Perhaps the Generic View would have looked something like this (not tested):</p>
<pre>@permission_required('calendars.add_eventtype')
def create_type(request):
    return create_object(request,
                         form_class = EventTypeForm,
                         post_save_redirect=reverse('list_type'),
                         template_name='eventtype_form.html',
                         extra_context={'create_form': True,
                                        'calendar_menu': CalendarName.menu.all(),})    </pre>
<p>After:</p>
<pre>class TypeCreateView(CreateView):
    template_name = 'eventtype_form.html'
    model = EventType
    form_class = EventTypeForm

    def get_success_url(self):
        if '_addanother' in self.request.POST:
            return reverse('create_type')
        return reverse('list_type')

    ## Override dispatch to apply the permission decorator
    @method_decorator(permission_required('calendars.add_eventtype'))
    def dispatch(self, request, *args, **kwargs):
        return super(TypeCreateView, self).dispatch(request, *args, **kwargs)

    ## Additional context
    def get_context_data(self, **kwargs):
        context = super(TypeCreateView, self).get_context_data(**kwargs)
        context['calendar_menu'] = CalendarName.menu.all()
        context['create_form'] = True
        return context </pre>
<p>One of the benefits of the class based views is to be able to override individual methods. Here the <code>get_success_url</code> method can handle the extra functionality of the &#8220;Add Another&#8221; button.</p>
]]></content:encoded>
			<wfw:commentRss>http://dashdrum.com/blog/2011/11/class-based-views-createview-example/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Class Based Views &#8211; UpdateView Example</title>
		<link>http://dashdrum.com/blog/2011/11/class-based-views-updateview-example/</link>
		<comments>http://dashdrum.com/blog/2011/11/class-based-views-updateview-example/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 18:41:07 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[class based views]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://dashdrum.com/blog/?p=301</guid>
		<description><![CDATA[Yet another simple example. I basically just took the DeleteView example and changed a couple of things. Before: @permission_required('calendars.change_eventtype') def update_type(request,id): return update_object(request, model=EventType, object_id=id, template_name='eventtype_form.html', post_save_redirect=reverse('list_type'), extra_context = {'calendar_menu': CalendarName.menu.all()}) After: class TypeUpdateView(UpdateView): template_name = 'eventtype_form.html' model = EventType &#8230; <a href="http://dashdrum.com/blog/2011/11/class-based-views-updateview-example/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Yet another simple example.  I basically just took the <a href="http://dashdrum.com/blog/2011/11/class-based-views-deleteview-example/" title="Class Based Views – DeleteView Example"><code>DeleteView</code></a> example and changed a couple of things.</p>
<p>Before:</p>
<pre>@permission_required('calendars.change_eventtype')
def update_type(request,id):
    return update_object(request,
                         model=EventType,
                         object_id=id,
                         template_name='eventtype_form.html',
                         post_save_redirect=reverse('list_type'),
                       extra_context = {'calendar_menu': CalendarName.menu.all()})</pre>
<p>After:</p>
<pre>class TypeUpdateView(UpdateView):
    template_name = 'eventtype_form.html'
    model = EventType

    def get_success_url(self):
        return reverse('list_type')

    ## Override dispatch to apply the permission decorator
    @method_decorator(permission_required('calendars.change_eventtype'))
    def dispatch(self, request, *args, **kwargs):
        return super(TypeUpdateView, self).dispatch(request, *args, **kwargs)

    ## Additional context
    def get_context_data(self, **kwargs):
        context = super(TypeUpdateView, self).get_context_data(**kwargs)
        context['calendar_menu'] = CalendarName.menu.all()
        return context </pre>
<p>With another example, the generic view declared a form_class instead of a model.   The model declaration is not necessary since the related model is tied to the form in its meta section.  However, in the class based generic view, both were required (or a queryset could have also been used).  I guess the related model info doesn&#8217;t make its way back to the class.  Hmmmm.</p>
]]></content:encoded>
			<wfw:commentRss>http://dashdrum.com/blog/2011/11/class-based-views-updateview-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Class Based Views &#8211; DeleteView Example</title>
		<link>http://dashdrum.com/blog/2011/11/class-based-views-deleteview-example/</link>
		<comments>http://dashdrum.com/blog/2011/11/class-based-views-deleteview-example/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 02:46:58 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[class based views]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://dashdrum.com/blog/?p=292</guid>
		<description><![CDATA[Another simple one &#8211; this time a DeleteView from delete_object. Before: @permission_required('b2c.delete_b2ctrack') def delete_track(request,id): track = get_object_or_404(B2CTrack, pk=id) if track.allow_delete: return delete_object(request, model=B2CTrack, object_id=id, post_delete_redirect=reverse('track_list'), template_name='track_confirm_delete.html') else: return HttpResponseRedirect(reverse('track_view', kwargs = {'pk':id} )) After: class TrackDeleteView(DeleteView): template_name = 'track_confirm_delete.html' model &#8230; <a href="http://dashdrum.com/blog/2011/11/class-based-views-deleteview-example/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Another simple one &#8211; this time a <code>DeleteView</code> from <code>delete_object</code>.</p>
<p>Before:</p>
<pre>@permission_required('b2c.delete_b2ctrack')
def delete_track(request,id):
    track = get_object_or_404(B2CTrack, pk=id)
    if track.allow_delete:
        return delete_object(request,
                             model=B2CTrack,
                             object_id=id,
                             post_delete_redirect=reverse('track_list'),
                             template_name='track_confirm_delete.html')
    else:
        return HttpResponseRedirect(reverse('track_view', kwargs = {'pk':id} ))</pre>
<p>After:</p>
<pre>class TrackDeleteView(DeleteView):
    template_name = 'track_confirm_delete.html'
    model = B2CTrack

    def get_success_url(self):
        return reverse('track_list')

    ## Override dispatch to apply the permission decorator
    @method_decorator(permission_required('b2c.delete_b2ctrack'))
    def dispatch(self, request, *args, **kwargs):
        return super(TrackDeleteView, self).dispatch(request, *args, **kwargs)

    ## Only return object if the allow_delete property is True
    def get_object(self, *args, **kwargs):
        object = super(TrackDeleteView,self).get_object(*args, **kwargs)
        if object.allow_delete:
            return object
        else:
            raise Http404</pre>
<p>The old code would redirect back to the view for the same object if the <code>allow_delete</code> property was false. (allow_delete is a property I use on my models to check for dependent DB entries)  Since one has to monkey with the URL to even attempt a delete of an object that isn&#8217;t allowed, I decided a 404 was more appropriate.  Lesson for the User: Don&#8217;t Monkey with URLs!!</p>
]]></content:encoded>
			<wfw:commentRss>http://dashdrum.com/blog/2011/11/class-based-views-deleteview-example/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Class Based Views &#8211; DetailView Example</title>
		<link>http://dashdrum.com/blog/2011/11/class-based-views-detailview-example/</link>
		<comments>http://dashdrum.com/blog/2011/11/class-based-views-detailview-example/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 20:34:52 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[class based views]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://dashdrum.com/blog/?p=289</guid>
		<description><![CDATA[This is a simple example that shows how to convert the object_detail generic view to the class based DetailView. Before: @permission_required('b2c.view_b2ctrack') def view_track(request,id): return object_detail(request, queryset=B2CTrack.objects.all(), object_id=id, template_name='track_detail.html') After: class TrackDetailView(DetailView): template_name = 'track_detail.html' model = B2CTrack ## Override dispatch &#8230; <a href="http://dashdrum.com/blog/2011/11/class-based-views-detailview-example/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is a simple example that shows how to convert the <code>object_detail</code> generic view to the class based <code>DetailView</code>.</p>
<p>Before:</p>
<pre>@permission_required('b2c.view_b2ctrack')
def view_track(request,id):
    return object_detail(request,
                         queryset=B2CTrack.objects.all(),
                         object_id=id,
                         template_name='track_detail.html')</pre>
<p>After:</p>
<pre>class TrackDetailView(DetailView):
    template_name = 'track_detail.html'
    model = B2CTrack

    ## Override dispatch to apply the permission decorator
    @method_decorator(permission_required('b2c.view_b2ctrack'))
    def dispatch(self, *args, **kwargs):
        return super(TrackDetailView, self).dispatch(*args, **kwargs)  </pre>
<p>Only odd thing I encountered was that the new View wants to see the ID of the object named &#8216;pk&#8217;, instead of &#8216;id&#8217; that I was using.  The DEV branch of Django includes the <code>pk_url_kwarg</code> variable that allows a rename, but it isn&#8217;t available in v1.3.</p>
<p>Note that I could have used <code>queryset</code> instead of <code>model</code> to specify the data source.  Either will give the same result in this example.</p>
]]></content:encoded>
			<wfw:commentRss>http://dashdrum.com/blog/2011/11/class-based-views-detailview-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More on Class Based Views &#8211; Redirect If Data Missing</title>
		<link>http://dashdrum.com/blog/2011/11/more-on-class-based-views-redirect-if-data-missing/</link>
		<comments>http://dashdrum.com/blog/2011/11/more-on-class-based-views-redirect-if-data-missing/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 01:20:27 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[class based views]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://dashdrum.com/blog/?p=283</guid>
		<description><![CDATA[In this view, rather than raising a 404 if a piece of data is missing, I redirect back to a page where the user can specify the value. def list_session(request): event_id = request.session.get('event_id',None) try: event = Event.objects.get(pk=event_id) except: #No event &#8230; <a href="http://dashdrum.com/blog/2011/11/more-on-class-based-views-redirect-if-data-missing/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In this view, rather than raising a 404 if a piece of data is missing, I redirect back to a page where the user can specify the value.</p>
<pre>def list_session(request):
    event_id = request.session.get('event_id',None)
    try:
        event = Event.objects.get(pk=event_id)
    except:  #No event - back to staff page to select
        return HttpResponseRedirect(reverse('staff'))

    queryset = B2CSession.objects.filter(event = event)

    params = {'queryset': queryset,
              'paginate_by': DEFAULT_PAGINATION,
              'template_name': 'session_list.html',
              'extra_context': {'event': event,
                                'session': session}}
    return object_list(request, **params)</pre>
<p>I wanted to implement this same functionality using a class based view, so I looked into the available methods to override.  The <code>dispatch</code> method was really the only choice.  My solution:</p>
<pre>def dispatch(self, request, *args, **kwargs):
        ## If there is no event_id set in the session, return to staff page for a chance to select one
        try:
            self.event = Event.objects.get(pk=request.session.get('event_id',None))
        except Event.DoesNotExist:
            return HttpResponseRedirect(reverse('staff'))
        ## Normal processing
        return super(ListSessionView, self).dispatch(request, *args, **kwargs)  </pre>
<p>What do you think?  Is this the best way to make this work? Leave your comments below.</p>
]]></content:encoded>
			<wfw:commentRss>http://dashdrum.com/blog/2011/11/more-on-class-based-views-redirect-if-data-missing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Eclipse Setup for Django</title>
		<link>http://dashdrum.com/blog/2011/10/my-eclipse-setup-for-django/</link>
		<comments>http://dashdrum.com/blog/2011/10/my-eclipse-setup-for-django/#comments</comments>
		<pubDate>Sat, 01 Oct 2011 13:50:44 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://dashdrum.com/blog/?p=276</guid>
		<description><![CDATA[Documenting my Eclipse setup as I install onto a fresh Ubuntu 11.04 machine. First, is the choice of Eclipse package. There are several that will work for Python/Django &#8211; basically any of the Language IDE focused bundles. This time I &#8230; <a href="http://dashdrum.com/blog/2011/10/my-eclipse-setup-for-django/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://eclipse.org/"><img class="alignleft" title="Eclipse Logo" src="http://www.planeteclipse.org/planet/images/faces/eclipseface.png" alt="Eclipse Logo" width="76" height="74" hspace="11" vspace="11" /></a>Documenting my <a title="Eclipse" href="http://eclipse.org/" target="_blank">Eclipse</a> setup as I install onto a fresh <a title="Ubuntu" href="http://ubuntu.com" target="_blank">Ubuntu</a> 11.04 machine.</p>
<p>First, is the choice of Eclipse package. There are several that will work for Python/Django &#8211; basically any of the Language IDE focused bundles. This time I am using the Java EE setup (v3.7.1), but I have also installed the standard Java and C/C++ builds with success.</p>
<p>I wish that there was an install procedure for Eclipse that would setup the menus, etc. The package available in the Ubuntu Software Center is usually an older version (currently 3.5) and is a basic install only. It is up to the user to add the additional features desired. Instead, I download the package, extract to /opt, and setup the menus myself.</p>
<p>Next is <a href="http://aptana.com/products/studio3/" target="_blank">Aptana Studio 3</a>. This includes PyDev (which supplies Python and Django functionality), web tools, Ruby support, and other goodies. For Python/Django support only, I have used the standalone <a href="http://pydev.org/" target="_blank">PyDev</a> install instead. However, once PyDev is installed, the Aptana install complains if installed later.</p>
<p>Also important is version control support. Eclipse comes with CVS included, and clients for other systems are available. Since I use Subversion, I install the <a href="http://subclipse.tigris.org/" target="_blank">Subclipse</a> add-in from Tigrs. Check the version numbers of both your Eclipse and svn installs to select the correct Subclipse package. Eclipse will complain about JavaHL not being available the first time SVN is used. There is a setting in Eclipse (under Team/SVN) to switch to the SVNKit client.</p>
<p>I have also used <a href="http://eclipsesql.sourceforge.net/index.php" target="_blank">Eclipse SQL Explorer</a> for database access. It is a bit of a fight to get the proper drivers and configuration all figured out, but worth it to have DB commands within the Eclipse environment here. Read more about SQL Explorer in <a href="http://dashdrum.com/blog/2009/12/eclipse-sql-explorer/" target="_blank">this earlier post</a>.</p>
<p>That is pretty much it. I may at a later date talk about setting up virtual environments in Eclipse, so stay tuned.</p>
<p>Any questions or suggestions? Please post a comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://dashdrum.com/blog/2011/10/my-eclipse-setup-for-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

