From 09cfea3466e34d6df16e98bb12a4f364410378c7 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Thu, 15 Mar 2012 12:23:09 -0700 Subject: [PATCH] Added info on mimetype and typo fix. --- category/django.html | 2 +- drafts/ajax-and-django-views.html | 4 ++-- feeds/all-en.atom.xml | 8 ++++---- feeds/all.atom.xml | 8 ++++---- feeds/django.atom.xml | 6 +++--- feeds/posts.atom.xml | 2 +- index.html | 2 +- posts/ajax-and-django-views.rst | 4 ++-- tag/django.html | 2 +- tag/forms.html | 2 +- tag/models.html | 2 +- tag/python.html | 2 +- user-friendlier-model-forms.html | 2 +- 13 files changed, 23 insertions(+), 23 deletions(-) diff --git a/category/django.html b/category/django.html index d34984f7..3f198cf5 100644 --- a/category/django.html +++ b/category/django.html @@ -69,7 +69,7 @@
Two guys... and Python.

User-friendlier model forms

-
Published: 03-12-2012 +
Published: 03-13-2012 by Kenneth tags: django python forms models diff --git a/drafts/ajax-and-django-views.html b/drafts/ajax-and-django-views.html index 18951d45..09178647 100644 --- a/drafts/ajax-and-django-views.html +++ b/drafts/ajax-and-django-views.html @@ -190,7 +190,7 @@

AJAX Views

mimetype="application/json") return super(PonyAjaxUpdateView, self).form_invalid(form) -

Again, nothing special in the view. We use an UpdateView so we can, technically, still use the view without AJAX. Assuming that the POST data that comes in validates on the form, our form_valid 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 HttpResponse 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 201 for Created is a very polite thing to do, especially if you think your view will end up as part of an ad hoc API.

+

Again, nothing special in the view. We use an UpdateView so we can, technically, still use the view without AJAX. Assuming that the POST data that comes in validates on the form, our form_valid 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 HttpResponse or one with a message, like demonstrated above, is enough. When returning JSON, make sure to include the mimetype="application/json" in your HttpResponse. Without the proper mimetype you will be dealing with text/html content instead of JSON. If your view creates new objects or deletes old ones, returning proper status codes, like 201 for Created is a very polite thing to do, especially if you think your view will end up as part of an ad hoc API.

Similarly, above, if the form is invalid, we serialize the form errors (note: not the non_field_errors() errors) and send them back to the view. The script we wrote above, apply_form_field_error can be called in a loop for each error in the list and update your form so the users know what they did wrong.

note Did you notice the braces package we used in the above view? That's a package we released from a previous blog post on custom class-based view mixins. You can get it on Github or PyPI.
@@ -240,7 +240,7 @@

jQuery

}); }); -

Again, nothing special if you're used to doing AJAX requests in jQuery. We stop the form from actually submitting using preventDefault() 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 data- 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 data 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.

+

Again, nothing special if you're used to doing AJAX requests in jQuery. We stop the form from actually submitting using preventDefault() 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 data- 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 data 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.

We then provide success and error attributes for the .ajax() call. These can be provided outside of the .ajax() call, which is very useful if your code is more modular, but we rarely have need of that approach. The success 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.

The error 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.

diff --git a/feeds/all-en.atom.xml b/feeds/all-en.atom.xml index 70139f6b..421e2a7b 100644 --- a/feeds/all-en.atom.xml +++ b/feeds/all-en.atom.xml @@ -1,5 +1,5 @@ -brack3thttp://brack3t.com2012-03-12T14:27:07ZUser-friendlier model forms2012-03-12T14:27:07ZKennethtag:brack3t.com,2012-03-12:/user-friendlier-model-forms.html/<p>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 <tt class="docutils literal">rent</tt> 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 &quot;call for details&quot; or &quot;on approved credit&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.</p> +brack3thttp://brack3t.com2012-03-13T16:31:00ZUser-friendlier model forms2012-03-13T16:31:00ZKennethtag:brack3t.com,2012-03-13:/user-friendlier-model-forms.html/<p>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 <tt class="docutils literal">rent</tt> 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 &quot;call for details&quot; or &quot;on approved credit&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.</p> <div class="section" id="model"> <h2>Model</h2> <p>Let's go over our <tt class="docutils literal">Rent</tt> 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 <tt class="docutils literal">Rent</tt> model, but I won't show them here.</p> @@ -154,7 +154,7 @@ class FloorplanBaseForm(CommunityKwargModelFormMixin, UserKwargModelFormMixin, <p>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.</p> <p>Thanks to Kevin Diale for pointing out our oversight on <tt class="docutils literal">getattr</tt>/<tt class="docutils literal">setattr</tt>.</p> </div> -What We Use2012-03-05T14:58:02ZKennethtag:brack3t.com,2012-03-05:/what-we-use.html/<p>We've noticed several people publishing lists of what they use to do their work lately, so we thought we'd join in. +What We Use2012-03-05T15:00:46ZKennethtag:brack3t.com,2012-03-05:/what-we-use.html/<p>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, from setting up servers, to <a class="reference external" href="http://djangoproject.com">Django</a> and <a class="reference external" href="http://python.org">Python</a> 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 @@ -242,7 +242,7 @@ most common items.</p> <h2><a class="toc-backref" href="#id14">Summary</a></h2> <p>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.</p> </div> -Our Custom Mixins2012-03-02T13:30:34ZChristag:brack3t.com,2012-03-02:/our-custom-mixins.html/<p><strong>UPDATE</strong>: We've released a <a class="reference external" href="https://github.com/brack3t/django-braces">Github repo</a> and a <a class="reference external" href="http://pypi.python.org/pypi/django-braces/0.1.0">PyPI package</a> with our mixins. Feel free to fork and submit new ones through a pull-request.</p> +Our Custom Mixins2012-03-02T16:48:32ZChristag:brack3t.com,2012-03-02:/our-custom-mixins.html/<p><strong>UPDATE</strong>: We've released a <a class="reference external" href="https://github.com/brack3t/django-braces">Github repo</a> and a <a class="reference external" href="http://pypi.python.org/pypi/django-braces/0.1.0">PyPI package</a> with our mixins. Feel free to fork and submit new ones through a pull-request.</p> <p>Let's just start out and say it, <strong>Class Based Views</strong>. 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 lacking but I find a lot of people, especially on <a class="reference external" href="http://reddit.com/r/django">Reddit</a>, refuse to use them. For whatever reason, it's a hard @@ -535,7 +535,7 @@ straightforward and works much like Django's built-in <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 any questions, leave a comment or hit us up on Twitter.</p> </div> -Generic Layouts in Crispy Forms2012-02-29T18:11:15ZKennethtag:brack3t.com,2012-02-29:/generic-layouts-in-crispy-forms.html/<p>Just a quick tip and sanity check, today, about something I ran into with <a class="reference external" href="https://github.com/maraujop/django-crispy-forms">django-crispy-forms</a>, the awesome new form library from Miguel Araujo.</p> +Generic Layouts in Crispy Forms2012-02-29T21:05:18ZKennethtag:brack3t.com,2012-02-29:/generic-layouts-in-crispy-forms.html/<p>Just a quick tip and sanity check, today, about something I ran into with <a class="reference external" href="https://github.com/maraujop/django-crispy-forms">django-crispy-forms</a>, the awesome new form library from Miguel Araujo.</p> <p>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 <tt class="docutils literal"><span class="pre">django-uni-form</span></tt> to <tt class="docutils literal"><span class="pre">django-crispy-forms</span></tt>. It's a pretty painless transition, actually. Just do some find-and-replace across your files, basically changing any instance of <tt class="docutils literal">uni-</tt> to <tt class="docutils literal">crispy-</tt> (well, and <tt class="docutils literal">form</tt> to <tt class="docutils literal">forms</tt>), 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 <tt class="docutils literal">Layout</tt> objects that <tt class="docutils literal"><span class="pre">django-crispy-forms</span></tt> gives us.</p> diff --git a/feeds/all.atom.xml b/feeds/all.atom.xml index 20f3f259..eec400c7 100644 --- a/feeds/all.atom.xml +++ b/feeds/all.atom.xml @@ -1,5 +1,5 @@ -brack3thttp://brack3t.com2012-03-12T14:27:07ZUser-friendlier model forms2012-03-12T14:27:07ZKennethtag:brack3t.com,2012-03-12:/user-friendlier-model-forms.html/<p>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 <tt class="docutils literal">rent</tt> 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 &quot;call for details&quot; or &quot;on approved credit&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.</p> +brack3thttp://brack3t.com2012-03-13T16:31:00ZUser-friendlier model forms2012-03-13T16:31:00ZKennethtag:brack3t.com,2012-03-13:/user-friendlier-model-forms.html/<p>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 <tt class="docutils literal">rent</tt> 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 &quot;call for details&quot; or &quot;on approved credit&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.</p> <div class="section" id="model"> <h2>Model</h2> <p>Let's go over our <tt class="docutils literal">Rent</tt> 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 <tt class="docutils literal">Rent</tt> model, but I won't show them here.</p> @@ -154,7 +154,7 @@ class FloorplanBaseForm(CommunityKwargModelFormMixin, UserKwargModelFormMixin, <p>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.</p> <p>Thanks to Kevin Diale for pointing out our oversight on <tt class="docutils literal">getattr</tt>/<tt class="docutils literal">setattr</tt>.</p> </div> -What We Use2012-03-05T14:58:02ZKennethtag:brack3t.com,2012-03-05:/what-we-use.html/<p>We've noticed several people publishing lists of what they use to do their work lately, so we thought we'd join in. +What We Use2012-03-05T15:00:46ZKennethtag:brack3t.com,2012-03-05:/what-we-use.html/<p>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, from setting up servers, to <a class="reference external" href="http://djangoproject.com">Django</a> and <a class="reference external" href="http://python.org">Python</a> 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 @@ -242,7 +242,7 @@ most common items.</p> <h2><a class="toc-backref" href="#id14">Summary</a></h2> <p>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.</p> </div> -Our Custom Mixins2012-03-02T13:30:34ZChristag:brack3t.com,2012-03-02:/our-custom-mixins.html/<p><strong>UPDATE</strong>: We've released a <a class="reference external" href="https://github.com/brack3t/django-braces">Github repo</a> and a <a class="reference external" href="http://pypi.python.org/pypi/django-braces/0.1.0">PyPI package</a> with our mixins. Feel free to fork and submit new ones through a pull-request.</p> +Our Custom Mixins2012-03-02T16:48:32ZChristag:brack3t.com,2012-03-02:/our-custom-mixins.html/<p><strong>UPDATE</strong>: We've released a <a class="reference external" href="https://github.com/brack3t/django-braces">Github repo</a> and a <a class="reference external" href="http://pypi.python.org/pypi/django-braces/0.1.0">PyPI package</a> with our mixins. Feel free to fork and submit new ones through a pull-request.</p> <p>Let's just start out and say it, <strong>Class Based Views</strong>. 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 lacking but I find a lot of people, especially on <a class="reference external" href="http://reddit.com/r/django">Reddit</a>, refuse to use them. For whatever reason, it's a hard @@ -535,7 +535,7 @@ straightforward and works much like Django's built-in <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 any questions, leave a comment or hit us up on Twitter.</p> </div> -Generic Layouts in Crispy Forms2012-02-29T18:11:15ZKennethtag:brack3t.com,2012-02-29:/generic-layouts-in-crispy-forms.html/<p>Just a quick tip and sanity check, today, about something I ran into with <a class="reference external" href="https://github.com/maraujop/django-crispy-forms">django-crispy-forms</a>, the awesome new form library from Miguel Araujo.</p> +Generic Layouts in Crispy Forms2012-02-29T21:05:18ZKennethtag:brack3t.com,2012-02-29:/generic-layouts-in-crispy-forms.html/<p>Just a quick tip and sanity check, today, about something I ran into with <a class="reference external" href="https://github.com/maraujop/django-crispy-forms">django-crispy-forms</a>, the awesome new form library from Miguel Araujo.</p> <p>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 <tt class="docutils literal"><span class="pre">django-uni-form</span></tt> to <tt class="docutils literal"><span class="pre">django-crispy-forms</span></tt>. It's a pretty painless transition, actually. Just do some find-and-replace across your files, basically changing any instance of <tt class="docutils literal">uni-</tt> to <tt class="docutils literal">crispy-</tt> (well, and <tt class="docutils literal">form</tt> to <tt class="docutils literal">forms</tt>), 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 <tt class="docutils literal">Layout</tt> objects that <tt class="docutils literal"><span class="pre">django-crispy-forms</span></tt> gives us.</p> diff --git a/feeds/django.atom.xml b/feeds/django.atom.xml index 4730c560..8bfa9fd1 100644 --- a/feeds/django.atom.xml +++ b/feeds/django.atom.xml @@ -1,5 +1,5 @@ -brack3thttp://brack3t.com2012-03-12T14:27:07ZUser-friendlier model forms2012-03-12T14:27:07ZKennethtag:brack3t.com,2012-03-12:/user-friendlier-model-forms.html/<p>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 <tt class="docutils literal">rent</tt> 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 &quot;call for details&quot; or &quot;on approved credit&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.</p> +brack3thttp://brack3t.com2012-03-13T16:31:00ZUser-friendlier model forms2012-03-13T16:31:00ZKennethtag:brack3t.com,2012-03-13:/user-friendlier-model-forms.html/<p>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 <tt class="docutils literal">rent</tt> 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 &quot;call for details&quot; or &quot;on approved credit&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.</p> <div class="section" id="model"> <h2>Model</h2> <p>Let's go over our <tt class="docutils literal">Rent</tt> 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 <tt class="docutils literal">Rent</tt> model, but I won't show them here.</p> @@ -154,7 +154,7 @@ class FloorplanBaseForm(CommunityKwargModelFormMixin, UserKwargModelFormMixin, <p>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.</p> <p>Thanks to Kevin Diale for pointing out our oversight on <tt class="docutils literal">getattr</tt>/<tt class="docutils literal">setattr</tt>.</p> </div> -Our Custom Mixins2012-03-02T13:30:34ZChristag:brack3t.com,2012-03-02:/our-custom-mixins.html/<p><strong>UPDATE</strong>: We've released a <a class="reference external" href="https://github.com/brack3t/django-braces">Github repo</a> and a <a class="reference external" href="http://pypi.python.org/pypi/django-braces/0.1.0">PyPI package</a> with our mixins. Feel free to fork and submit new ones through a pull-request.</p> +Our Custom Mixins2012-03-02T16:48:32ZChristag:brack3t.com,2012-03-02:/our-custom-mixins.html/<p><strong>UPDATE</strong>: We've released a <a class="reference external" href="https://github.com/brack3t/django-braces">Github repo</a> and a <a class="reference external" href="http://pypi.python.org/pypi/django-braces/0.1.0">PyPI package</a> with our mixins. Feel free to fork and submit new ones through a pull-request.</p> <p>Let's just start out and say it, <strong>Class Based Views</strong>. 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 lacking but I find a lot of people, especially on <a class="reference external" href="http://reddit.com/r/django">Reddit</a>, refuse to use them. For whatever reason, it's a hard @@ -447,7 +447,7 @@ straightforward and works much like Django's built-in <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 any questions, leave a comment or hit us up on Twitter.</p> </div> -Generic Layouts in Crispy Forms2012-02-29T18:11:15ZKennethtag:brack3t.com,2012-02-29:/generic-layouts-in-crispy-forms.html/<p>Just a quick tip and sanity check, today, about something I ran into with <a class="reference external" href="https://github.com/maraujop/django-crispy-forms">django-crispy-forms</a>, the awesome new form library from Miguel Araujo.</p> +Generic Layouts in Crispy Forms2012-02-29T21:05:18ZKennethtag:brack3t.com,2012-02-29:/generic-layouts-in-crispy-forms.html/<p>Just a quick tip and sanity check, today, about something I ran into with <a class="reference external" href="https://github.com/maraujop/django-crispy-forms">django-crispy-forms</a>, the awesome new form library from Miguel Araujo.</p> <p>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 <tt class="docutils literal"><span class="pre">django-uni-form</span></tt> to <tt class="docutils literal"><span class="pre">django-crispy-forms</span></tt>. It's a pretty painless transition, actually. Just do some find-and-replace across your files, basically changing any instance of <tt class="docutils literal">uni-</tt> to <tt class="docutils literal">crispy-</tt> (well, and <tt class="docutils literal">form</tt> to <tt class="docutils literal">forms</tt>), 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 <tt class="docutils literal">Layout</tt> objects that <tt class="docutils literal"><span class="pre">django-crispy-forms</span></tt> gives us.</p> diff --git a/feeds/posts.atom.xml b/feeds/posts.atom.xml index 426e55b6..67dea56e 100644 --- a/feeds/posts.atom.xml +++ b/feeds/posts.atom.xml @@ -1,5 +1,5 @@ -brack3thttp://brack3t.com2012-03-05T14:58:02ZWhat We Use2012-03-05T14:58:02ZKennethtag:brack3t.com,2012-03-05:/what-we-use.html/<p>We've noticed several people publishing lists of what they use to do their work lately, so we thought we'd join in. +brack3thttp://brack3t.com2012-03-05T15:00:46ZWhat We Use2012-03-05T15:00:46ZKennethtag:brack3t.com,2012-03-05:/what-we-use.html/<p>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, from setting up servers, to <a class="reference external" href="http://djangoproject.com">Django</a> and <a class="reference external" href="http://python.org">Python</a> 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 diff --git a/index.html b/index.html index 4a4fe765..de484e59 100644 --- a/index.html +++ b/index.html @@ -69,7 +69,7 @@
Two guys... and Python.

User-friendlier model forms

-
Published: 03-12-2012 +
Published: 03-13-2012 by Kenneth tags: django python forms models diff --git a/posts/ajax-and-django-views.rst b/posts/ajax-and-django-views.rst index bd0b8dd1..9d3e5ce5 100644 --- a/posts/ajax-and-django-views.rst +++ b/posts/ajax-and-django-views.rst @@ -134,7 +134,7 @@ So now let's get down to the good stuff. The following view is very generic and mimetype="application/json") return super(PonyAjaxUpdateView, self).form_invalid(form) -Again, nothing special in the view. We use an ``UpdateView`` so we can, technically, still use the view without AJAX. Assuming that the POST data that comes in validates on the form, our ``form_valid`` 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 ``HttpResponse`` 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 ``201`` for ``Created`` is a very polite thing to do, especially if you think your view will end up as part of an ad hoc API. +Again, nothing special in the view. We use an ``UpdateView`` so we can, technically, still use the view without AJAX. Assuming that the POST data that comes in validates on the form, our ``form_valid`` 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 ``HttpResponse`` or one with a message, like demonstrated above, is enough. When returning JSON, make sure to include the ``mimetype="application/json"`` in your ``HttpResponse``. Without the proper *mimetype* you will be dealing with ``text/html`` content instead of JSON. If your view creates new objects or deletes old ones, returning proper status codes, like ``201`` for ``Created`` is a very polite thing to do, especially if you think your view will end up as part of an ad hoc API. Similarly, above, if the form is invalid, we serialize the form errors (note: not the ``non_field_errors()`` errors) and send them back to the view. The script we wrote above, ``apply_form_field_error`` can be called in a loop for each error in the list and update your form so the users know what they did wrong. @@ -197,7 +197,7 @@ jQuery }); }); -Again, nothing special if you're used to doing AJAX requests in jQuery. We stop the form from actually submitting using ``preventDefault()`` 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 ``data-`` 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 ``data`` 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. +Again, nothing special if you're used to doing AJAX requests in jQuery. We stop the form from actually submitting using ``preventDefault()`` 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 ``data-`` 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 ``data`` 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. We then provide ``success`` and ``error`` attributes for the ``.ajax()`` call. These *can* be provided outside of the ``.ajax()`` call, which is very useful if your code is more modular, but we rarely have need of that approach. The ``success`` 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. diff --git a/tag/django.html b/tag/django.html index d34984f7..3f198cf5 100644 --- a/tag/django.html +++ b/tag/django.html @@ -69,7 +69,7 @@
Two guys... and Python.

User-friendlier model forms

-
Published: 03-12-2012 +
Published: 03-13-2012 by Kenneth tags: django python forms models diff --git a/tag/forms.html b/tag/forms.html index 04ece48c..179f8902 100644 --- a/tag/forms.html +++ b/tag/forms.html @@ -69,7 +69,7 @@
Two guys... and Python.

User-friendlier model forms

-
Published: 03-12-2012 +
Published: 03-13-2012 by Kenneth tags: django python forms models diff --git a/tag/models.html b/tag/models.html index 04ece48c..179f8902 100644 --- a/tag/models.html +++ b/tag/models.html @@ -69,7 +69,7 @@
Two guys... and Python.

User-friendlier model forms

-
Published: 03-12-2012 +
Published: 03-13-2012 by Kenneth tags: django python forms models diff --git a/tag/python.html b/tag/python.html index f5947822..2542768c 100644 --- a/tag/python.html +++ b/tag/python.html @@ -69,7 +69,7 @@
Two guys... and Python.