Skip to content

Commit

Permalink
Merge branch 'master' of github.com:brack3t/brack3t.github.com
Browse files Browse the repository at this point in the history
  • Loading branch information
kennethlove committed Mar 15, 2012
2 parents 5c8b2cb + 09cfea3 commit 27ccfc5
Show file tree
Hide file tree
Showing 13 changed files with 23 additions and 23 deletions.
2 changes: 1 addition & 1 deletion category/django.html
Expand Up @@ -69,7 +69,7 @@ <h6>Two guys... and Python.</h6>
<article> <article>
<header> <header>
<h1><a href=".././user-friendlier-model-forms.html" class="slabtext">User-friendlier model forms</a></h1> <h1><a href=".././user-friendlier-model-forms.html" class="slabtext">User-friendlier model forms</a></h1>
<h6><span class="permalink">Published: <a href=".././user-friendlier-model-forms.html">03-12-2012</a></span> <h6><span class="permalink">Published: <a href=".././user-friendlier-model-forms.html">03-13-2012</a></span>
<span class="author">by <strong>Kenneth</strong></span> <span class="author">by <strong>Kenneth</strong></span>
<span class="tags">tags: <a href=".././tag/django.html">django</a> <a href=".././tag/python.html">python</a> <a href=".././tag/forms.html">forms</a> <a href=".././tag/models.html">models</a> </span> <span class="tags">tags: <a href=".././tag/django.html">django</a> <a href=".././tag/python.html">python</a> <a href=".././tag/forms.html">forms</a> <a href=".././tag/models.html">models</a> </span>


Expand Down
4 changes: 2 additions & 2 deletions drafts/ajax-and-django-views.html
Expand Up @@ -190,7 +190,7 @@ <h2>AJAX Views</h2>
<span class="x"> mimetype=&quot;application/json&quot;)</span> <span class="x"> mimetype=&quot;application/json&quot;)</span>
<span class="x"> return super(PonyAjaxUpdateView, self).form_invalid(form)</span> <span class="x"> return super(PonyAjaxUpdateView, self).form_invalid(form)</span>
</pre></div> </pre></div>
<p>Again, nothing special in the view. We use an <tt class="docutils literal">UpdateView</tt> so we can, technically, still use the view without AJAX. Assuming that the POST data that comes in validates on the form, our <tt class="docutils literal">form_valid</tt> method will fire, which checks to see if the request was made via AJAX and, if so, returns a success string. Quite often we like to return a serialized version of the object that was just created or updated, but that takes some special considerations when it comes to Django model objects. If you don't need the object back, returning a standard <tt class="docutils literal">HttpResponse</tt> or one with a message, like demonstrated above, is enough. If your view creates new objects or deletes old ones, returning proper status codes, like <tt class="docutils literal">201</tt> for <tt class="docutils literal">Created</tt> is a very polite thing to do, especially if you think your view will end up as part of an ad hoc API.</p> <p>Again, nothing special in the view. We use an <tt class="docutils literal">UpdateView</tt> so we can, technically, still use the view without AJAX. Assuming that the POST data that comes in validates on the form, our <tt class="docutils literal">form_valid</tt> method will fire, which checks to see if the request was made via AJAX and, if so, returns a success string. Quite often we like to return a serialized version of the object that was just created or updated, but that takes some special considerations when it comes to Django model objects. If you don't need the object back, returning a standard <tt class="docutils literal">HttpResponse</tt> or one with a message, like demonstrated above, is enough. When returning JSON, make sure to include the <tt class="docutils literal"><span class="pre">mimetype=&quot;application/json&quot;</span></tt> in your <tt class="docutils literal">HttpResponse</tt>. Without the proper <em>mimetype</em> you will be dealing with <tt class="docutils literal">text/html</tt> content instead of JSON. If your view creates new objects or deletes old ones, returning proper status codes, like <tt class="docutils literal">201</tt> for <tt class="docutils literal">Created</tt> is a very polite thing to do, especially if you think your view will end up as part of an ad hoc API.</p>
<p>Similarly, above, if the form is invalid, we serialize the form errors (note: not the <tt class="docutils literal">non_field_errors()</tt> errors) and send them back to the view. The script we wrote above, <tt class="docutils literal">apply_form_field_error</tt> can be called in a loop for each error in the list and update your form so the users know what they did wrong.</p> <p>Similarly, above, if the form is invalid, we serialize the form errors (note: not the <tt class="docutils literal">non_field_errors()</tt> errors) and send them back to the view. The script we wrote above, <tt class="docutils literal">apply_form_field_error</tt> can be called in a loop for each error in the list and update your form so the users know what they did wrong.</p>
<blockquote> <blockquote>
<span class="label label-info">note</span> Did you notice the <em>braces</em> package we used in the above view? That's a package we released from a previous blog post on <a class="reference external" href="http://brack3t.com/our-custom-mixins.html">custom class-based view mixins</a>. You can get it on <a class="reference external" href="https://github.com/brack3t/django-braces">Github</a> or <a class="reference external" href="http://pypi.python.org/pypi/django-braces/">PyPI</a>.</blockquote> <span class="label label-info">note</span> Did you notice the <em>braces</em> package we used in the above view? That's a package we released from a previous blog post on <a class="reference external" href="http://brack3t.com/our-custom-mixins.html">custom class-based view mixins</a>. You can get it on <a class="reference external" href="https://github.com/brack3t/django-braces">Github</a> or <a class="reference external" href="http://pypi.python.org/pypi/django-braces/">PyPI</a>.</blockquote>
Expand Down Expand Up @@ -240,7 +240,7 @@ <h3>jQuery</h3>
<span class="p">});</span> <span class="p">});</span>
<span class="p">});</span> <span class="p">});</span>
</pre></div> </pre></div>
<p>Again, nothing special if you're used to doing AJAX requests in jQuery. We stop the form from actually submitting using <tt class="docutils literal">preventDefault()</tt> on the submission event, then build a few variables. Luckily we can get the URL directly off the form; this is part of why we end up using the <tt class="docutils literal">data-</tt> attributes a lot, so we can separate our templates from our Javascript. We typically go through and name out the keys that we ant to send through to the backend view in the <tt class="docutils literal">data</tt> dict, but you could use serialization options provided by jQuery or another plugin. These just seem to have a lot of quirks that we'd rather not take into consideration (especially not for an example in a blog post). Our way is definitely more manual but less error-prone.</p> <p>Again, nothing special if you're used to doing AJAX requests in jQuery. We stop the form from actually submitting using <tt class="docutils literal">preventDefault()</tt> on the submission event, then build a few variables. Luckily we can get the URL directly off the form; this is part of why we end up using the <tt class="docutils literal">data-</tt> attributes a lot, so we can separate our templates from our Javascript. We typically go through and name out the keys that we want to send through to the backend view in the <tt class="docutils literal">data</tt> dict, but you could use serialization options provided by jQuery or another plugin. These just seem to have a lot of quirks that we'd rather not take into consideration (especially not for an example in a blog post). Our way is definitely more manual but less error-prone.</p>
<p>We then provide <tt class="docutils literal">success</tt> and <tt class="docutils literal">error</tt> attributes for the <tt class="docutils literal">.ajax()</tt> call. These <em>can</em> be provided outside of the <tt class="docutils literal">.ajax()</tt> call, which is very useful if your code is more modular, but we rarely have need of that approach. The <tt class="docutils literal">success</tt> function just prints out a message to the user, letting them know everything saved correctly. This is where you would update UI elements or whatever your use case requires.</p> <p>We then provide <tt class="docutils literal">success</tt> and <tt class="docutils literal">error</tt> attributes for the <tt class="docutils literal">.ajax()</tt> call. These <em>can</em> be provided outside of the <tt class="docutils literal">.ajax()</tt> call, which is very useful if your code is more modular, but we rarely have need of that approach. The <tt class="docutils literal">success</tt> function just prints out a message to the user, letting them know everything saved correctly. This is where you would update UI elements or whatever your use case requires.</p>
<p>The <tt class="docutils literal">error</tt> function turns the JSON string that our view returned into a Javascript object so we can dig through it more easily (no one likes to parse text). We loop through all of the provided errors and, depending on if their key indicates them to be global or field-specific, render them out to the page for the user. Again, this is where you'd want to update your interface.</p> <p>The <tt class="docutils literal">error</tt> function turns the JSON string that our view returned into a Javascript object so we can dig through it more easily (no one likes to parse text). We loop through all of the provided errors and, depending on if their key indicates them to be global or field-specific, render them out to the page for the user. Again, this is where you'd want to update your interface.</p>
</div> </div>
Expand Down
8 changes: 4 additions & 4 deletions feeds/all-en.atom.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>brack3t</title><link href="http://brack3t.com" rel="alternate"></link><link href="http://brack3t.com/feeds/all-en.atom.xml" rel="self"></link><id>http://brack3t.com</id><updated>2012-03-12T14:27:07Z</updated><entry><title>User-friendlier model forms</title><link href="http://brack3t.com/user-friendlier-model-forms.html" rel="alternate"></link><updated>2012-03-12T14:27:07Z</updated><author><name>Kenneth</name></author><id>tag:brack3t.com,2012-03-12:/user-friendlier-model-forms.html/</id><summary type="html">&lt;p&gt;Recently, in our large client project, we had need of fields, in a model form, that accepted multiple types of input, but sanitized the data for the model. For example, the &lt;tt class="docutils literal"&gt;rent&lt;/tt&gt; field, on the form, needs to handle a rent range (e.g. 900-1200), a single amount, or be overridden or extended by other bits of information, like &amp;quot;call for details&amp;quot; or &amp;quot;on approved credit&amp;quot;. Obviously we don't want to have to parse this out every time we read the data. So, enter our fields that tear data apart and put it together every time it passes through.&lt;/p&gt; <feed xmlns="http://www.w3.org/2005/Atom"><title>brack3t</title><link href="http://brack3t.com" rel="alternate"></link><link href="http://brack3t.com/feeds/all-en.atom.xml" rel="self"></link><id>http://brack3t.com</id><updated>2012-03-13T16:31:00Z</updated><entry><title>User-friendlier model forms</title><link href="http://brack3t.com/user-friendlier-model-forms.html" rel="alternate"></link><updated>2012-03-13T16:31:00Z</updated><author><name>Kenneth</name></author><id>tag:brack3t.com,2012-03-13:/user-friendlier-model-forms.html/</id><summary type="html">&lt;p&gt;Recently, in our large client project, we had need of fields, in a model form, that accepted multiple types of input, but sanitized the data for the model. For example, the &lt;tt class="docutils literal"&gt;rent&lt;/tt&gt; field, on the form, needs to handle a rent range (e.g. 900-1200), a single amount, or be overridden or extended by other bits of information, like &amp;quot;call for details&amp;quot; or &amp;quot;on approved credit&amp;quot;. Obviously we don't want to have to parse this out every time we read the data. So, enter our fields that tear data apart and put it together every time it passes through.&lt;/p&gt;
&lt;div class="section" id="model"&gt; &lt;div class="section" id="model"&gt;
&lt;h2&gt;Model&lt;/h2&gt; &lt;h2&gt;Model&lt;/h2&gt;
&lt;p&gt;Let's go over our &lt;tt class="docutils literal"&gt;Rent&lt;/tt&gt; model first. It's an abstract model so we can use it in multiple places (we have more than one logical model in the system that needs to deal with rent, this way we can use it multiple places without having to hold on to a huge amount of joins). We have several other abstract models that perform the same actions as our &lt;tt class="docutils literal"&gt;Rent&lt;/tt&gt; model, but I won't show them here.&lt;/p&gt; &lt;p&gt;Let's go over our &lt;tt class="docutils literal"&gt;Rent&lt;/tt&gt; model first. It's an abstract model so we can use it in multiple places (we have more than one logical model in the system that needs to deal with rent, this way we can use it multiple places without having to hold on to a huge amount of joins). We have several other abstract models that perform the same actions as our &lt;tt class="docutils literal"&gt;Rent&lt;/tt&gt; model, but I won't show them here.&lt;/p&gt;
Expand Down Expand Up @@ -154,7 +154,7 @@ class FloorplanBaseForm(CommunityKwargModelFormMixin, UserKwargModelFormMixin,
&lt;p&gt;Hopefully this gives you some ideas on how to make forms more user-friendly while maintaining solid model data on the backend. If you see something we could be doing better, please let us know in the comments.&lt;/p&gt; &lt;p&gt;Hopefully this gives you some ideas on how to make forms more user-friendly while maintaining solid model data on the backend. If you see something we could be doing better, please let us know in the comments.&lt;/p&gt;
&lt;p&gt;Thanks to Kevin Diale for pointing out our oversight on &lt;tt class="docutils literal"&gt;getattr&lt;/tt&gt;/&lt;tt class="docutils literal"&gt;setattr&lt;/tt&gt;.&lt;/p&gt; &lt;p&gt;Thanks to Kevin Diale for pointing out our oversight on &lt;tt class="docutils literal"&gt;getattr&lt;/tt&gt;/&lt;tt class="docutils literal"&gt;setattr&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt; &lt;/div&gt;
</summary><category term="django"></category><category term="python"></category><category term="forms"></category><category term="models"></category></entry><entry><title>What We Use</title><link href="http://brack3t.com/what-we-use.html" rel="alternate"></link><updated>2012-03-05T14:58:02Z</updated><author><name>Kenneth</name></author><id>tag:brack3t.com,2012-03-05:/what-we-use.html/</id><summary type="html">&lt;p&gt;We've noticed several people publishing lists of what they use to do their work lately, so we thought we'd join in. </summary><category term="django"></category><category term="python"></category><category term="forms"></category><category term="models"></category></entry><entry><title>What We Use</title><link href="http://brack3t.com/what-we-use.html" rel="alternate"></link><updated>2012-03-05T15:00:46Z</updated><author><name>Kenneth</name></author><id>tag:brack3t.com,2012-03-05:/what-we-use.html/</id><summary type="html">&lt;p&gt;We've noticed several people publishing lists of what they use to do their work lately, so we thought we'd join in.
Below are the tools we use nearly every day to do our work. If you don't know, our work is the entire stack, Below are the tools we use nearly every day to do our work. If you don't know, our work is the entire stack,
from setting up servers, to &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt; and &lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt; programming, to front-end web development and design. Obviously, from setting up servers, to &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt; and &lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt; programming, to front-end web development and design. Obviously,
with such a large area of work, we end up using a lot of different products and libraries, so, below is a list of our with such a large area of work, we end up using a lot of different products and libraries, so, below is a list of our
Expand Down Expand Up @@ -242,7 +242,7 @@ most common items.&lt;/p&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#id14"&gt;Summary&lt;/a&gt;&lt;/h2&gt; &lt;h2&gt;&lt;a class="toc-backref" href="#id14"&gt;Summary&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I think that pretty much covers the tools and libraries we end up touching in our day-to-day work. Our work and requirements are constantly changing, though, so this post might be one that we need to revist every six months or year. If you have any suggestions for new products to check out, or ways we can make our current favorites even better, let us know on Twitter or in the comments below. Thanks for reading.&lt;/p&gt; &lt;p&gt;I think that pretty much covers the tools and libraries we end up touching in our day-to-day work. Our work and requirements are constantly changing, though, so this post might be one that we need to revist every six months or year. If you have any suggestions for new products to check out, or ways we can make our current favorites even better, let us know on Twitter or in the comments below. Thanks for reading.&lt;/p&gt;
&lt;/div&gt; &lt;/div&gt;
</summary><category term="workflow"></category><category term="tools"></category></entry><entry><title>Our Custom Mixins</title><link href="http://brack3t.com/our-custom-mixins.html" rel="alternate"></link><updated>2012-03-02T13:30:34Z</updated><author><name>Chris</name></author><id>tag:brack3t.com,2012-03-02:/our-custom-mixins.html/</id><summary type="html">&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: We've released a &lt;a class="reference external" href="https://github.com/brack3t/django-braces"&gt;Github repo&lt;/a&gt; and a &lt;a class="reference external" href="http://pypi.python.org/pypi/django-braces/0.1.0"&gt;PyPI package&lt;/a&gt; with our mixins. Feel free to fork and submit new ones through a pull-request.&lt;/p&gt; </summary><category term="workflow"></category><category term="tools"></category></entry><entry><title>Our Custom Mixins</title><link href="http://brack3t.com/our-custom-mixins.html" rel="alternate"></link><updated>2012-03-02T16:48:32Z</updated><author><name>Chris</name></author><id>tag:brack3t.com,2012-03-02:/our-custom-mixins.html/</id><summary type="html">&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: We've released a &lt;a class="reference external" href="https://github.com/brack3t/django-braces"&gt;Github repo&lt;/a&gt; and a &lt;a class="reference external" href="http://pypi.python.org/pypi/django-braces/0.1.0"&gt;PyPI package&lt;/a&gt; with our mixins. Feel free to fork and submit new ones through a pull-request.&lt;/p&gt;
&lt;p&gt;Let's just start out and say it, &lt;strong&gt;Class Based Views&lt;/strong&gt;. Ooohhhh. Unfortunately the topic of class based views is &lt;p&gt;Let's just start out and say it, &lt;strong&gt;Class Based Views&lt;/strong&gt;. Ooohhhh. Unfortunately the topic of class based views is
thought of as somewhat of a dark art in the Django community. It doesn't help that the documentation is still thought of as somewhat of a dark art in the Django community. It doesn't help that the documentation is still
lacking but I find a lot of people, especially on &lt;a class="reference external" href="http://reddit.com/r/django"&gt;Reddit&lt;/a&gt;, refuse to use them. For whatever reason, it's a hard lacking but I find a lot of people, especially on &lt;a class="reference external" href="http://reddit.com/r/django"&gt;Reddit&lt;/a&gt;, refuse to use them. For whatever reason, it's a hard
Expand Down Expand Up @@ -535,7 +535,7 @@ straightforward and works much like Django's built-in &lt;tt class="docutils lit
Writing custom mixins helps to alleviate pain points in your project and make it faster to create new features, at least is has for us. If you have Writing custom mixins helps to alleviate pain points in your project and make it faster to create new features, at least is has for us. If you have
any questions, leave a comment or hit us up on Twitter.&lt;/p&gt; any questions, leave a comment or hit us up on Twitter.&lt;/p&gt;
&lt;/div&gt; &lt;/div&gt;
</summary><category term="django"></category><category term="CBVs"></category></entry><entry><title>Generic Layouts in Crispy Forms</title><link href="http://brack3t.com/generic-layouts-in-crispy-forms.html" rel="alternate"></link><updated>2012-02-29T18:11:15Z</updated><author><name>Kenneth</name></author><id>tag:brack3t.com,2012-02-29:/generic-layouts-in-crispy-forms.html/</id><summary type="html">&lt;p&gt;Just a quick tip and sanity check, today, about something I ran into with &lt;a class="reference external" href="https://github.com/maraujop/django-crispy-forms"&gt;django-crispy-forms&lt;/a&gt;, the awesome new form library from Miguel Araujo.&lt;/p&gt; </summary><category term="django"></category><category term="CBVs"></category></entry><entry><title>Generic Layouts in Crispy Forms</title><link href="http://brack3t.com/generic-layouts-in-crispy-forms.html" rel="alternate"></link><updated>2012-02-29T21:05:18Z</updated><author><name>Kenneth</name></author><id>tag:brack3t.com,2012-02-29:/generic-layouts-in-crispy-forms.html/</id><summary type="html">&lt;p&gt;Just a quick tip and sanity check, today, about something I ran into with &lt;a class="reference external" href="https://github.com/maraujop/django-crispy-forms"&gt;django-crispy-forms&lt;/a&gt;, the awesome new form library from Miguel Araujo.&lt;/p&gt;
&lt;p&gt;This morning, I converted the project we've been building for a client (currently some 1,700 or so files, counting templates, CSS, and icons) from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;django-uni-form&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;django-crispy-forms&lt;/span&gt;&lt;/tt&gt;. It's a pretty painless &lt;p&gt;This morning, I converted the project we've been building for a client (currently some 1,700 or so files, counting templates, CSS, and icons) from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;django-uni-form&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;django-crispy-forms&lt;/span&gt;&lt;/tt&gt;. It's a pretty painless
transition, actually. Just do some find-and-replace across your files, basically changing any instance of &lt;tt class="docutils literal"&gt;uni-&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;crispy-&lt;/tt&gt; (well, and &lt;tt class="docutils literal"&gt;form&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;forms&lt;/tt&gt;), and you're good to go. Then, however, I wanted to transition, actually. Just do some find-and-replace across your files, basically changing any instance of &lt;tt class="docutils literal"&gt;uni-&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;crispy-&lt;/tt&gt; (well, and &lt;tt class="docutils literal"&gt;form&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;forms&lt;/tt&gt;), and you're good to go. Then, however, I wanted to
convert two large forms that we have, which share 90% of their fields, to using the sharable &lt;tt class="docutils literal"&gt;Layout&lt;/tt&gt; objects that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;django-crispy-forms&lt;/span&gt;&lt;/tt&gt; gives us.&lt;/p&gt; convert two large forms that we have, which share 90% of their fields, to using the sharable &lt;tt class="docutils literal"&gt;Layout&lt;/tt&gt; objects that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;django-crispy-forms&lt;/span&gt;&lt;/tt&gt; gives us.&lt;/p&gt;
Expand Down

0 comments on commit 27ccfc5

Please sign in to comment.