attribute: Phillie Casablanca

Djangoで動的にフォーム(Form)のフィールド(field)を作る

Djangoの遊びプロジェクットをやっています。

そこで、ユーザが入力する項目から、複数選択可能チェックボックスのFormが作りたくて困っていました。

下記のモデルを定義しました:

models.py


class SkillCategory(models.Model):
name = models.CharField(max_length=50)

class Skill(models.Model):
category = models.ForeignKey(SkillCategory)
name = models.CharField(max_length=50)

Djangoの開発者らしいサイトから、So you want a dynamic formでの説明から、下記の答えがわかりました。

ここで、モデルで定義するSkillやSkillCategoryから、FormのFieldが動的に作成されます。
forms.py


from django import forms
from myapp.models import Skill
def get_categorized_skills():
    skills = {}
    for s in Skill.objects.values('pk', 'name', 'category__name').order_by('category__name'):
        if s['category__name'] not in skills.keys():
        skills[s['category__name']] = []
        skills[s['category__name']].append((s['pk'], s['name']))
    return skills

class SkillSelectionForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(SkillSelectionForm, self).__init__(*args, **kwargs)
        skills = get_categorized_skills()
        for idx, cat in enumerate(skills.keys()):
# ascii以外(日本語)の名前が使えるようにfield_name・display_nameを作成します。
field_name = u'category-%d' % (idx)
display_name = cat
            self.fields[field_name] = forms.MultipleChoiceField(choices=skills[cat],
label=display_name,
widget=forms.CheckboxSelectMultiple)

monkut // Sept. 13, 2009 // 10:07 p.m. // 1 Comments

DjangoのAdminユーザ名・パスワードを忘れた!

このサイトじゃないですが、この間また、パスワードを忘れました。

前回は、Shellに入って、パスワードのリセットしたんですが、それでも面倒くさい。
http://coderseye.com/2007/howto-reset-the-admin-password-in-django.html

今回、気がついたのは、新しいSUPERUSERを作っちゃえばと思って、楽にできました。
(Django 1.0からのコマンドです)
まず、manage.pyまたは、django-admin.pyで:


django-admin.py createsuperuser
Name: newadmin
E-mail: newadmin@fixed.com
Password:
Password (again):

monkut // Feb. 13, 2009 // 1:50 a.m. // 13492 Comments

GeoDjangoを試したところ

この間、ウインドウズでGeoDjangoのTutorialをやってみようと思いました。

まず、PostGresのダウンロードとインストール:
(最新のインストーラにはPOSTGISも入っているので、インストール時、PostGisをちゃんと選択しましょう)
http://www.postgresql.org/download/windows

それで、Djangoのインストール:
ここのインストーラをダウンロードして、インストールしました。
(ここで説明があります: http://geodjango.org/docs/install.html#geodjango-installer)
http://geodjango.org/windows/GeoDjango_Installer.exe

これがDjango 1.0とGDAL 1.5.0とPROJ.4をインストールしてくれて、ENVの変数を追加してくれます。

それで、ここのTutorialをやっている途中にTutorialが終っていると気が付きました。

しばらくやめようと考えたんですが、このリンクがでてきました:
http://code.google.com/p/geodjango-basic-apps/wiki/GeographicAdminQuickStart

最初、psycopg2のモジュールがインストールされていなくて、エラーがでました。
ビルドとインストールをしばらく苦労しましたが、やっと2.6用のウインドウズのインストーラが見つけました!
http://www.stickpeople.com/projects/python/win-psycopg/

これで手順をしっかり、従ったら、Adminの編集ができました。
(Step3はほぼ必要はないと思ったんですが、結局、そこでこけました。Step3を全てをやったら、無事にインストールができました。)

これから、これを使ってなんか面白いことができないのかを調べてみます。

monkut // Nov. 5, 2008 // 1:50 a.m. // 1 Comments

DjangoCon2008のビデオ

DjangoCon2008の各発表のビデオがYouTubeに載っています:

http://www.youtube.com/view_play_list?p=D415FAF806EC47A1

monkut // Oct. 8, 2008 // 12:03 a.m. // 1 Comments

Django参考集

この間これを見つけました。

MercurytideのDjango 1.0チートシートです:
http://www.mercurytide.co.uk/whitepapers/django-cheat-sheet/

よくDocumentationで探すものがのっています。

monkut // Oct. 1, 2008 // 10:23 p.m. // 1 Comments

Django Developer Interview

Floss weekly had a interview with Jacob Kaplan-Moss of the django development team.

It provides some nice background into django history and provides a nice intro to the general django development flow.

http://twit.tv/floss34

monkut // July 29, 2008 // 9:40 p.m. // 1 Comments

Syntax higlighting in posts

And an answer to my syntax highlighting question.
Now I just need the time to implement it.

http://www.djangosnippets.org/snippets/119/

UPDATE:
I wimped out and found prettify.js here:
http://code.google.com/p/google-code-prettify/

I initially looked at the snippets link, but was turned-off by having to do installs.
Where as with prettify I was able to accomplish what I wanted by just coping over the js and css files and adding a couple of lines to my template.

monkut // June 30, 2008 // 9:31 a.m. // 1470 Comments

Category link listing complete

Well, I think my category list solution has arrived.

For awhile there I thought I would have to stop using generic views and write a view to handle passing the data to the template. But actually it turned out to be pretty easy. Basically, I'm just not familar with the terms used in django, otherwise I may have figured out this earlier.

The orginal tutorial I ran through wasn't the django one so it left out some key structural explanations.
Now I think I've got it.

You define a urlpattern to handle incoming request and direct them to views. The views job is to render the template and provide a response.

The template variable is called context. Which is the part I overlooked.
Re-reading the generic views documentation I noticed that "django.views.generic.date_based.archive_index" has an optional argument, "extra_context". This option allows you to pass additional data to the template.
(See http://www.djangoproject.com/documentation/0.96/generic_views/#django-views-generic-date-based-archive-index)

Then by reviewing the filtering documentation I was able to send the data I wanted to the template, and heres the added info in the urls.py file:

[code]
(r'^$','django.views.generic.date_based.archive_index',
{'queryset': Post.objects.all(),
'date_field': 'date',
'extra_context':{
'categories':Post.objects.values('category').distinct().order_by('category')
},
}
),

[/code]

I'm understanding django more clearly now as I continue to hack away.
I don't yet feel like I'm programming yet though, it just feels like I'm configuring and tweaking settings.

monkut // June 12, 2008 // 11:33 a.m. // 1 Comments

How do I make category list links

I'm trying to add a sidebar of links that provides a list of categories from my posts.
The categories are dynamic so I don't want to hard code the category names.

I found what I think is a solution to the urls.py side of the issue (*maybe*) here:
http://www.b-list.org/weblog/2006/nov/16/django-tips-get-most-out-generic-views/

Basically, the solution involves creating a wrapper function to a generic view to provide added filtering via category.

I think that does what I want to actually display the categories by date, but now to add the actual links themselves to the template.

The only thing is, now I don't see how to provide a queryset result to the template.
I see that somehow the "latest" object magically appears in my main archive template, but how do I give it a filtered query set? (At least I think that's what I want)

As I understand, latest will only give me a subset of my posts, so I won't be able to get all possible categories. Actually getting a full set of data seems wasteful, but I assume there's some kind of filter I can do on the queryset that will give me the category list. It would seem pretty trivial from an sql perspective.

Oh well, the search continues...

monkut // June 11, 2008 // 11:53 a.m. // 105 Comments

Notes on urls.py

I was confused for quite some time about how to get multiple generic views in a single urlpatterns definition in the urls.py file.

The examples I had been looking at would define urlpatterns something like this:

[code]

urlpatterns = patterns('django.views.generic.date_based',
(r'^$','archive_index',
{'queryset': Post.objects.all(),
'date_field': 'date',
'allow_empty':True,
}),
)

[/code]

And until today I couldn't figure out how to get multple view types in there.
The first value given to patterns seemed to restrict what views could be used.

Well I finally ran across the documentation (http://www.djangoproject.com/documentation/0.96/url_dispatch/), and apparently that first string entry definition is the view prefix, which just means you can reduce the amount of writing if your using the same base view for all your views.

In other words if you want to use multiple views in the same urlpatterns def you just leave that first value blank:

[code]
urlpatterns = patterns('',
(r'^articles/(\d{4})/$', 'mysite.news.views.year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'mysite.news.views.month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'mysite.news.views.article_detail'),
)
[/code]

I'm sure its helpfull if your writting a lot of patterns, but it confused me for quite a while.
Maybe if the various examples defined this with "prefix=" I would have caught on earlier without having to dig through the documentation.

monkut // May 28, 2008 // 8:59 p.m. // 0 Comments

On to the next task, feeds

Well, I briefly attempted to replace freecomments with the standard(?) more featured comments frame work, but ran into some issues. Basically, I think I'm mis-understanding something. I was hoping to add a website field so commenters could post thier websites as many sites do. However, I couldn't (quickly) figure out how to get a user identified. (when I tried to move over the user name field was removed).
If I got that working I was hoping to get openid used, so users could just login with thier yahoo or google id to add comments, or maybe add a Captcha to avoid comment spam.

Oh well, I guess basic comments should be good enough until I feel a real need otherwise.

Now on to my next tasks feeds.
Django apparently has a good feeds framework, and I expect this to go quick when I eventually dig in and look into it.
http://www.djangoproject.com/documentation/syndication_feeds/

Then I guess it's really about time to decide on a name and layout. Design was always the most time consuming element for me.

monkut // May 1, 2008 // 4:01 a.m. // 0 Comments

And now with comments

Well I've got this up and running now with comments via django's freecomments framework.
This appears to be a very simple commenting system, so I'll probably try to move over to the main commenting framework noted here:

http://www.guindilla.eu/blog/2006/10/21/comment-and-karma-functions-django-framework/

Wish me luck.

monkut // April 20, 2008 // 10:14 a.m. // 143 Comments

Thanks Regex Coach

I was having trouble with getting my urls to match using regex in the django urls.py.

I was trying to get a single detailed post working using the generic view, "date-based object detail".
http://www.djangoproject.com/documentation/0.96/generic_views/#django-views-generic-date-based-object-detail

Once I got the regex right I was able to gradually debug through the rest of my issues to get it working.
I still don't fully understand the urlpatterns setting, but I understand it a little more now.

A single entry in the pattern file seems to take the following structure:
([regex for the url], [target function name to pass data to], [dictionary of additional options to pass to the function])

I'm using the ?P<name> tags in the regex, which will additionally pass the resulting information to the target function defined using the reference name in the <name> space. Other than regex itself, this part was probably what took the longest to understand.

I just want to say thanks for regex coach, I'm sure there are other similar tools out there, but I remembered this tool back when I was fighting with regex in perl. Simple but very helpful for discovering if the expression your thinking of actually matches your target text string.
http://weitz.de/regex-coach/

(And also the webmonkey cheetsheet and special characters references I've been using these since I first started learning html back in 98 or so)

monkut // April 17, 2008 // 9:16 a.m. // 3 Comments

Beyond first steps

So i've gotten more comfortable with Django.

And I've realized I now want to move beyond the initial simple blog example I initially followed.
(http://blog.disqus.net/2007/03/11/a-django-primer/)

It was a great frist step, but now to build more of a real site you need some extra features.
There are a couple of things I realized that I needed to add to the initial data model.

Mainly categories and a slug.

I first read about slugs on the django site, but didn't understand them.
Now that I wanted to link back to a historical single entry I realized that there needs to be some kind of identifier for a particular post, and slugs appear to be commonly used.

So I needed to update the model while at the same time not wanting to lose my previous notes.
Which means I apparently have to drop down into mysql and run the alter table commands myself.

This was a little daunting when I first read, "If you do care about deleting data, you’ll have to execute the ALTER TABLE statements manually in your database.". They always make it sound so easy.

Ok, so it wasn't that hard.

But, I didn't know the structure of the tables that django expects, but I remembered running across a command in the django tutorial that spat out the need sql commands to create tables, "python manage.py sql [appname]". So I ran this command and it gave me just what I needed the expected inputs for the columns I needed to add.

Next to alter the tables.

Entering mysql was easy enough, just entering 'mysql' on the command line.
But, I needed to enter the password, 'mysql -p' will gave the password prompt, then to connect to the db. (I didn't remember the password or the name of the db I created initially, luckily this is all in the settings.py file). So "connect " did the job there, then I was at the alter table add line.

And it seems to work. At least I'm not getting page errors anymore after I changed the model and ran syncdb...

Now on to the undocumented but documented commenting system:
http://code.djangoproject.com/wiki/UsingFreeComment

monkut // April 15, 2008 // 7:42 a.m. // 1 Comments

Notes on getting django started

After following the web faction recommended screen cast and the blog easy app tutorial mentioned in the previous post I still had some issues.

1. It wasn't clear to me how to reflect changes made at first. I kept seeing the "this is your first page" page.
Resolved by: using /home/username/webapps/django/apache2/bin/stop then start

2. The admin page was not using the formatting I saw in the tutorials.
In the screen cast a similar issue was seen, and he checked the apache2/log/error.log where errors to files not found were reported. I didn't see any errors like this.

Resolved by:
I checked the settings.py file in my project and this is found:

# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/media/'

Ok, so media (css, JS, etc) should be in this media file, but where is this directory?

A little searching came up with the answer.

Apparently, I had to add the following to "/django/apache2/conf/httpd.conf":

This added to the LoadModule list at the top:
LoadModule alias_module /home/username/webapps/django/apache2/modules/mod_alias.so

and this to the bottom of file:


SetHandler default

Alias /media /home/username/lib/python2.5/django/contrib/admin/media

Formatting fixed!

monkut // April 15, 2008 // 7:19 a.m. // 1 Comments