読者です 読者をやめる 読者になる 読者になる

謎言語使いの徒然

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

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

Django Python 日記

コレまでの履歴

  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 をセットし、ユーザごとにモデルが一つだけ生成されるようにします。