Django for Designers/CRUD: Difference between revisions

imported>Aldeka
imported>Aldeka
 
(8 intermediate revisions by the same user not shown)
Line 1:
== Part 4: CRUD ==
 
<div class="instructor">Time: 2 hours, 25 minutes</div>
 
<div class="instructor">Right now, we have a nice website that displays data from our database. Unfortunately, though, while we have a mock bookmark form in the app header, currently the only way to create new bookmarks is in the Python shell. That's not fun at all.</div>
Line 110 ⟶ 112:
<source lang="python">
def index(request):
if request.method == "'POST"':
form = BookmarkForm(request.POST)
if form.is_valid():
Line 204 ⟶ 206:
 
<source lang="python">
from django.shortcuts import render, get_object_or_404, redirect
from bookmarks.models import Bookmark, Tag
from bookmarks.forms import BookmarkForm
Line 294 ⟶ 296:
If you try this out, you'll see that our JS-y form makes real bookmarks, just like the old version of our form did! However, it's putting junk in our bookmarks list on the page; we have to reload to actually see the bookmark our ajax call created.
 
There's several ways we could fix this. <div class="instructor">We could make our views.py send back a JSON serialization of our bookmark data, and have our JS file turn that into a list element somehow (using either a JS template or a giant string). Or we could have Django do the template rendering for us, and send our JS script the raw HTML we want it to use. This is called AHAH (Asychronous HTML and HTTP), or sometimes PJAX.</div>
 
For the sake of speed and simplicity, we'll go with the latter. First, though, we need to refactor our templates a little.
Line 363 ⟶ 365:
<div class="instructor">What are we doing here? First, we're turning our request.POST test into a true choice -- we no longer go on to send back the full index.html rendered template if the request is a POST. Second, if we manage to create a bookmark successfully, we send back just our bookmark.html -- not the full index.html -- rendered with the data for our new bookmark.</div>
 
Finally, let's edit the success function in our script.js file to use this rendered data instead of printing nonsense:
Reload your development server and your web page, and try creating a bookmark. It should appear right away on the page now!
 
<source lang="bashjavascript">
Try submitting the form with a tag but no URL. <div class="instructor">Nothing happens, right?</div> If you check the server log in your terminal window, you'll see an error message:
success: function(data){
 
$('.error').hide();
<source lang="bash">
$('.bookmarks').prepend(data);
ValueError: The view bookmarks.views.index didn't return an HttpResponse object.
}
</source>
 
Reload your development server and your web page, and try creating a bookmark. It should appear right away on the page now!
Eek. Our index view doesn't handle the case where the request is a POST, but the form doesn't validate, and Django noticed this and returned an error. Let's fix this by editing the ''index'' function in ''views.py'' again:
 
Try submitting the form with a tag but no URL. <div class="instructor">Nothing happens, right?Eek.</div> IfWe you checksee the serverbrowser logtry into yourrender terminalthe entire page inside the window,page--because youwe'llre seeredirecting back to the annormal errorindex message:view!
 
Eek. Our index view doesn't properly handle the case where the request is a POST, but the form doesn't validate, and Django noticed this and returned an error. Let's fix this by editing the ''index'' function in ''views.py'' again:
 
<source lang="python">
Line 417 ⟶ 424:
 
<div class="instructor">In the real world, if you were doing lots of this sort of manipulation, instead of AHAH you might want to be using a Javascript framework such as Backbone to avoid getting confused, messy code. You'd also want to use templates for the elements that your Javascript hooks are adding and modifying. Ideally, you'd want those templates to be the same ones that your Django application used, to avoid repeating yourself! There's a lot of ways Django users deal with these problems. One way to do this is to use Django as an API data engine and do all the routing, application logic, and template rendering--at least, on the JS-heavy pages--via a Javascript-based template language. [http://django-tastypie.readthedocs.org/en/latest/ Tastypie] is a popular Django application for making APIs for this sort of thing. Another approach is to teach Django to speak the language of a JS-based templating language. Projects like [https://github.com/yavorskiy/django-handlebars django-handlebars] or [https://github.com/mjumbewu/djangobars djangobars] are examples of this approach!</div>
 
[[Django_for_Designers/Styling|Next page]]
Anonymous user