謎言語使いの徒然

適当に気になった技術や言語を流すブログ。

【モデル利用】Django 初心者がコミュニティサイト的な何かにチャレンジしてみる

コレまでの履歴

  1. 【インストール編】Django 初心者がコミュニティサイト的な何かにチャレンジしてみる
  2. 【プロジェクト作成】Django 初心者がコミュニティサイト的な何かにチャレンジしてみる
  3. 【モデル作成】Django 初心者がコミュニティサイト的な何かにチャレンジしてみる

モデル作成は気がつけば前回やってたので、モデルを軽めに使ってみる。
(Djangoチュートリアル位のカンジで)
便利かも知れんけど、今日は admin は封印。コンソールだけで行く。

先ずはプロジェクトディレクトリへ移動して次のコマンドを叩く。

manage.py shell

すると、Python おなじみのコンソール画面が出てくる。
前回作ったモデルを軽めに弄ってみようと思う。

>>> from django.contrib.auth.models import User
>>> User.objects.all()
[<User: admin>]
>>>

うん、syncdb で作った管理ユーザがいる。
早速これを抽出してみる。

>>> admin = User.objects.filter(username="admin")
>>> admin
[<User: admin>]
>>>

コトのついでに、追加ユーザ情報も付加してみる。

>>> from community.models import UserProfile
>>> profile = UserProfile(target_user=admin , nick_name="azalea")

しかし上記はエラーになる。何でも、target_user には User のインスタンスを指定しろというが、、、
30分もさ迷った上、admin を help してみたらわかった。

>>> help(admin)
Help on QuerySet in module django.db.models.query object:

class QuerySet(__builtin__.object)
 |  Represents a lazy database lookup for a set of objects.
 |

は!?QuerySet 型!?ぱっと見意味不明。
ユーザ名でフィルタしたのに、、、、と思ってよくよく考えると、「遅延実行評価」するためにこの段階ではUserインスタンスじゃないのね、、、。
考えてみたら理解できるが、知らないときつい。
(type, instance 関数で型判定ができる10分以上探したぜヽ(;´Д`)ノ)


改めて挑戦

>>> admin = admin.get()
>>> type(admin)
<class 'django.contrib.auth.models.User'>
>>>

今度は大丈夫そうだ。

>>> profile = UserProfile(target_user=admin , nick_name="azalea" , home_page="http://www.white-azalea.net")
>>> profile.save()

ヨシヨシいい子だ。
保存もできたらしい。次は、これで取り出しをしてみる。

パターン1、ユーザを元に引き出す。

>>> UserProfile.objects.filter(target_user=admin).get()
<UserProfile: azalea>
>>>

よしOK.
パターン2、ユーザ型から情報を引き出す。
http://djangoproject.jp/doc/ja/1.0/topics/auth.html#id13
ここにしたがってやってみよー

>>> admin.get_profile()

やってみるとわかるが、get_profile なんてメソッドねえよ!と怒られる。
どうも settings.py が読み込まれていないらしい。まぁ、いいかということで、必須のパラメータを設定する。

>>> AUTH_PROFILE_MODULE = 'community.userprofile'

いざ機を取り直して、、、と思ったら。

>>> admin.get_profile()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "C:\Python26\Lib\site-packages\django\contrib\auth\models.py", line 284,
in get_profile
    self._profile_cache = model._default_manager.get(user__id__exact=self.id)
  File "C:\Python26\Lib\site-packages\django\db\models\manager.py", line 93, in
get
    return self.get_query_set().get(*args, **kwargs)
  File "C:\Python26\Lib\site-packages\django\db\models\query.py", line 333, in g
et
    clone = self.filter(*args, **kwargs)
  File "C:\Python26\Lib\site-packages\django\db\models\query.py", line 519, in f
ilter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "C:\Python26\Lib\site-packages\django\db\models\query.py", line 537, in _
filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "C:\Python26\Lib\site-packages\django\db\models\sql\query.py", line 1415,
 in add_q
    can_reuse=used_aliases)
  File "C:\Python26\Lib\site-packages\django\db\models\sql\query.py", line 1313,
 in add_filter
    negate=negate, process_extras=process_extras)
  File "C:\Python26\Lib\site-packages\django\db\models\sql\query.py", line 1478,
 in setup_joins
    "Choices are: %s" % (name, ", ".join(names)))
FieldError: Cannot resolve keyword 'user' into field. Choices are: home_page, id
, nick_name, target_user

は!? 「user」がフィールドに含まれてないからダメとか言いやがったぞこいつ!
しかもその下の join レベルで「home_page, id, nick_name, target_user」から選べ、、、って、、、(;・∀・)
まさかと思いつつ model を変更して syncdb する。

class UserProfile(models.Model):
    user = models.ForeignKey(User,unique=True)
    nick_name = models.TextField(unique=True,max_length=64)
    home_page = models.URLField(verify_exists=False,null=True,blank=True)
    def __unicode__(self):
        return self.nick_name

そして上記手順でサクっと。

>>> from django.contrib.auth.models import User
>>> from community.models import *
>>> AUTH_PROFILE_MODULE = 'community.userprofile'
>>> admin = User.objects.filter(username="admin").get()
>>> profile = UserProfile(user=admin,nick_name="azalea")
>>> profile.save()
>>> admin.get_profile()
<UserProfile: azalea>
>>>

うごきやがった、、、、、、
ドキュメントに書いとけ!こういう決まりごとわっ!!!
参考。公式ドキュメント
http://djangoproject.jp/doc/ja/1.0/topics/auth.html#id13

ユーザプロファイルを利用するには、まず、ユーザにひもづけて保存したい情報を入れるためのフィールドや持たせたいメソッド、そして User モデルへの ForeignKey を持ったモデルを定義します。 ForeignKey には unique=True をセットし、ユーザごとにモデルが一つだけ生成されるようにします。