Fernando Correia’s Weblog

October 28, 2008

Exploring Pinax – Part 5

Filed under: Software Development — Fernando Correia @ 7:50 pm
Tags: ,

Proceeding with my project to learn how to develop a Django web application over Pinax, I build two simple forms: one for submitting a new item, and another to show an item.

As one reader commented, up to this point I’m not really using any Pinax feature other than the website structure itself, like authentication, templates and menus. I’m starting with a basic Django application. I hope to add soon features like notification, messaging, tagging, gravatar.

So, in this sprint I started by defining two URLs:

  • /pastebin/ to submit a new item
  • /pastebin/<uuid>/ to view a submitted item

This is what my apps/oxybeles/urls.py file looks like:

from django.conf.urls.defaults import *
from oxybeles.models import PastedItem

info_dict = {
    'queryset': PastedItem.objects.all(),
    'slug_field': 'uuid',
}

urlpatterns = patterns('',
    url(r'^$', 'oxybeles.views.new', name='oxybeles_new'),
    url(r'^(?P<slug>[-0-9a-f]{36})/$',
        'django.views.generic.list_detail.object_detail',
        info_dict,
        'oxybeles_detail'),
)

I also updated apps/oxybeles/models.py so it knows how to build a URL for a pasted item:

def get_absolute_url(self):
    return ('oxybeles_detail', (), { 'slug': self.uuid })
get_absolute_url = models.permalink(get_absolute_url)

I wrote a simple form class in apps/oxybeles/forms.py:

from django import forms 
from django.utils.translation import ugettext_lazy as _ 

from oxybeles.models import PastedItem 

class PastedItemForm(forms.ModelForm):
    class Meta():
        model = PastedItem
        fields = ('text',)

    def __init__(self, user = None, *args, **kwargs):
        self.user = user
        super(PastedItemForm, self).__init__(*args, **kwargs)

And finally I wrote in apps/oxybeles/views.py the view function that is in charge of the form for submitting new items:

from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect, get_host
from django.template import RequestContext
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext, ugettext_lazy as _
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required

from oxybeles.models import PastedItem
from oxybeles.forms import PastedItemForm

def new(request, form_class=PastedItemForm, template_name="oxybeles/new.html"):
    """
    Form for pasting new items.
    """
    form = form_class()
    if request.method == 'POST':
        if request.POST["action"] == "paste":
            form = form_class(request.user, request.POST)
            if form.is_valid():
                item = form.save(commit=False)
                item.user = request.user
                item.save()
                request.user.message_set.create(
                    message=ugettext("The new pasted item was saved."))
                    # some problem with ugettext_lazy here
                return HttpResponseRedirect(reverse('oxybeles_detail',
                                            args=(item.uuid,)))
    return render_to_response(template_name,
                              { "form": form, },
                              context_instance=RequestContext(request))
new = login_required(new)

Finally, I wrote the two templates.

templates/oxybeles/new.html:

{% extends "site_base.html" %}

{% load i18n %}

{% block head_title %}{% trans "Paste Bin" %}{% endblock %}

{% block body %}
<div id="basic-form">
<fieldset>
<legend>{% trans "New Item" %}</legend>
<form id="pastebin_new_form" method="POST" action="">
<div>{{ form.non_field_errors }}</div>
<div>{{ form.text.errors }}</div>
<div>{{ form.text }}</div>
<div><input type="hidden" name="action" value="paste" />
<input type="submit" value="paste" class="button" /></div>
</form>
</fieldset>
</div>
{% endblock %}

templates/oxybeles/pasteditem_detail.html:

{% extends "site_base.html" %}

{% load i18n %}

{% block head_title %}{% trans "Paste Bin" %}{% endblock %}

{% block body %}
<h1>Pasted Item</h1>
<pre>
<p>{{ object.text }}</p>
</pre>
{% endblock %}

And this is the final result:

http://127.0.0.1:8000/pastebin/

http://127.0.0.1:8000/pastebin/47d33482-a936-453a-8d4a-88aada4ebc44/

So, the basic app is in place. The source is in GitHub. In the next article I plan to implement a command to send a pasted item to a user, using Pinax’s features.

About these ads

6 Comments »

  1. You should draw the figure to show the relation among those files. In fact, I can see the good result but I don’t know why it can give the result like that.
    TT

    Comment by Anonymous — November 11, 2008 @ 8:51 am

  2. These postings are great. I have been learning python/django/pinax for about 6/2/0.4 months (respectively) now.

    I am having trouble though. I created a new tab and I want pass along the username to that view function, but I am getting an error. My app is in ..\py_03\app\cell and I am using the basic_project from pinax.

    In site_base.html I setup the new tab like so,
    {% trans “Cell” %}
    I also updated the tabs.css as indicated in the pinax online tutorial for adding tabs. The new tab does appear.

    ..\py_03\apps\cell\view.py
    def cell(request, username, template_name=”cell/base.html”, name = “whatisthis”):
    return render_to_response(template_name, { ‘user’: username.username,
    ‘name’: template_name })

    ..\py_03\templates\cell\base.html
    {% extends “site_base.html” %}
    {% load i18n %}
    {% block rtab_id %}id=”cell_tab”{% endblock %}
    {% block subnav %}
    {% if user.is_authenticated %}

    Hello there
    And the name = {{ name }}, ta da!

    {% else %}
     
    {% endif %}
    {% endblock %}

    ..\py_03\apps\cell\urls.py
    urlpatterns = patterns(”,
    url(r’^(?P[\w]+)/$’, direct_to_template, {“template”: “cell/base.html”}),
    )

    After I login, I get this message:
    Caught an exception while rendering: Reverse for ‘py_03.cell’ with arguments ‘(,)’ and keyword arguments ‘{}’ not found.

    I think ‘py_03.cell’ should be ‘py_03.apps.cell’ but can’t see how to do that. The “About” page is an app in the apps folder, and somehow that is found without a path thru ..\apps\..

    Comment by mgag — November 13, 2008 @ 6:36 pm

  3. my first posting, obvisouly it got hacked up because of the embedded html… lets try this,
    in site_base.html,

    {% trans “Cell” %}

    Comment by mgag — November 13, 2008 @ 6:38 pm

  4. Anonymous: I agree it is a lot of files. I suggest you take a look at the Django tutorial to understand how they fit together: http://docs.djangoproject.com/en/dev/intro/tutorial01/

    Comment by fernandoacorreia — November 13, 2008 @ 8:45 pm

  5. mgag: I’m still learning as well. I suggest you try to get help on the mailing list http://groups.google.com/group/django-users or on IRC at irc://irc.freenode.net/django

    Comment by fernandoacorreia — November 13, 2008 @ 8:48 pm

  6. Can you tell me why your paste button is nicely formatted while mine is a simple button on Mac OS X. Did you change the css file?

    Comment by Ali — July 10, 2010 @ 8:03 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Rubric Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: