Using .raw method of Django’s QuerySet
Today, I show you to use .raw method of Django’s QuerySet. The method is powerful and it can manipurate data in DB even if a column is not appear in Model’s field.
Of cause you can choice to use executing raw query by db connection directory. But, using raw method of QuerySet is more comfy. The method allow you to map the values in DB to the objects manually.
Ok, now let me show you a example. Consider a model calss, named Post, like this:
class Post(models.Model):
title = models.CharField(max_length=255)
body = models.CharField(max_length=255)
The model is simple and common what in like everyday we write. And then, try to change the schema of it directory:
sqlite> ALTER TABLE demoapp_post ADD COLUMN "slug" varchar(255);
sqlite> .schema demoapp_post
CREATE TABLE "demoapp_post" (
"id" integer NOT NULL PRIMARY KEY,
"title" varchar(255) NOT NULL,
"body" varchar(255) NOT NULL,
"slug" varchar(255));
just now, I added a column named ‘slug’. The column and model fields have a difference now. This ‘slug’ appears in sqlite db column, but not in the model.
And try to insert a row:
sqlite> INSERT INTO demoapp_post ("title", "body", "slug") VALUES ("test", "test body", "test slug");
sqlite> SELECT * FROM demoapp_post;
1|test|test body|test slug
Then let’s consider how we can get the value of slug (‘test slug’).
Use .raw method
The easiest way is ‘adding a field to the model and migrating the existed DB’. Yes, I know. but, sometime we should get a value from DB even if the column is not in the model fields.
Then, you might want to use raw method?
We can write a SQL directory as a argument to raw method. and the return value of the SQL will be mapped to a Model called the raw method, like this:
>>> post = Post.objects.raw("SELECT * FROM demoapp_post")[0]
>>> post.title
u'test'
>>> post.body
u'test body'
>>> post.slug
u'test slug'
>>> post.nothing
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Post' object has no attribute 'nothing'
Yeah! the value of ‘slug’ was showed up. In common way, we can’t get the vaule..:
>>> post = Post.objects.all()[0]
>>> post.title
u'test'
>>> post.body
u'test body'
>>> post.slug
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Post' object has no attribute 'slug'
Mapping the attribute more flexible
And then, by specifying the ‘translations’ attribute, we can change the mapping from DB value to Model attribute.
Ok next, let’s try to get the value of ‘slug’ column, through ‘urlslug’ attribute of a model:
>>> post = Post.objects.raw("SELECT * FROM demoapp_post", translations={'slug': 'urlslug'})[0]
>>> post.slug
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Post' object has no attribute 'slug'
>>> post.urlslug
u'test slug'
aw, it’s spookey, though.
(I checked above codes with Django 1.6)
好きなプリキュアからアニメをオススメするWebアプリ作った プリキュア Advent Calendar 2013 (2日目)
プリキュア Advent Calendar 2日目担当の @hirokiky です。
1日目 に @drillbits 氏が面白いもの作ってて非常に悔しい思いをしています。私もプリキュアにからめたネタでコードを書いたという話です。
作ったもの
作ったものは「自分の好きなプリキュアを選択していけばオススメのアニメが分かるWebアプリ」です。
こんな人におすすめです。
- 自分はたしかにプリキュアが好きだけど、他にどんな面白いアニメがあるだろう。
- 新作のアニメはひと通り観ているが、面白いものを見つけるのにも時間を取られてしまう。
- プリキュア以外で自分の趣向を表現できない
そういった疑問に答えるためのWebアプリケーションです。
今日から「今晩見るアニメ」に悩む必要はありません。ただあなたは「好きなプリキュアのキャラを選択する」 だけでいいのです。 そうすればこのWebアプリケーションが、即座にあなたの観るべきオススメのアニメを紹介してくれます。
というのは煽りです
というのは煽りですが、それなりにはできました。 デプロイもしてないのでスクリーンショットでもみていきましょう。
好きなプリキュアを選ぶ画面です。
ユーザー名を入力した後に、プリキュアの各キャラを「Like」「Soso」「Unlike」に設定していきます。 ここでのポイントは 心を鬼にしてUnlikeをつけること です。Likeばっかりつけてると後々いい結果がでません。
入力できました。 キュアダイアモンドとキュアロゼッタをUnlikeにしてますが気にしないでください。
さてここでsubmitボタンを押すとすごい画面が表示されます。
各プリキュアに関連する単語(詳細後述)とユーザーの入力を突き合わせた何かです。 ここのページの上部にあるフォームに、アニメの紹介文(英語)を入れます。
そしてsubmitすると、そのアニメ(紹介文)がユーザーにとって好まれるものか、そうでないかを返します。 とりあえず今回は プリキュアの紹介文 を入れてみました。
結果
Likeと表示されました。 私はプリキュアが好きなようです。
さて、さきほどいった「プリキュアに関連する単語」とは何だったのでしょうか。 これは各プリキュアの紹介文から抽出した、そのキャラたる単語(特徴語)です。
各プリキュアのデータも参照できます。
各プリキュアの名前: プリキュアの紹介文(英文)が見えると思います。 ここに入力された「名前」「紹介文」から先ほどの入力フォームや、特徴語を作っています。
なので正直にいうと、選択肢として用意するのはプリキュアじゃなくてもできます。
実装:PythonとMongoDB
開発には Python を使っています:
- 言語: Python2.7
- フレームワーク: Pyramid 1.5
- 永続化: MongoDB 2.2.4
コードみてください
動かしてみる
おそらくこんなかんじで動きます:
git clone https://github.com/hirokiky/curehack
sudo apt-get install mongodb
cd curehack
python setup.py develop
pserve development.ini
フィルタリングはスパムフィルターで行った
アニメの推奨にはスパムフィルターを使っています。
各プリキュアに対する[好き|嫌い]が、メールでいうところの[スパム|スパムじゃない]と同じと考えると分かりやすいです。 あるプリキュアを「好き」とすれば、そのプリキュアに対する説明文から特徴語を抽出して学習させます。 そのユーザー入力を通して得た好き嫌いのデータを元に、対象になるアニメの説明文をフィルタリングします。
さっきのごちゃっとしたのがそれです。
あとは単純ベイズフィルタとかいう魔法にかければうまくいきます。 実はこれは「集合知プログラミング」という本のサンプルコードを参考に使っています。 今回はそのバックエンドをMongoDBに対応させる処理を書いています。
まとめ
- 好きなプリキュアを選ぶとオススメのアニメを紹介するWebアプリを作った
これから開発を続けて、お遊びサービスとして公開するのも良いかと思いますが、 私が壊滅的に飽き性なのでそれはないと思います。
ちなみにこのコードは以前の プリキュアハッカソン で書いたものです。 頑張った割に紹介とかしてなかったのでこの期に書いて見ました。
以上です。