DjangoのManyToManyFieldへの追加と削除

2010-12-22
このエントリーをはてなブックマークに追加

データ設計をするときに、多対多になるケースがあります。たいていのフレームワーク、というかO/Rマッパーは多対多をサポートしており、Djangoも例外ではありません。

が、多対多のモデルへの追加と削除が意外とわかりにくかったので、メモ。

class ServiceCategory(models.Model):

name = models.CharField(max_length=256)

class Service(models.Model):

servicecategory = models.ManyToManyField(ServiceCategory)
name = models.CharField(max_length=256)

というモデルがあったとして、Serviceというモデルへデータを登録する際のservicecategoryへの追加と削除です。

_service = Service()
_service.save()

_service.servicecategory.add(ServiceCategory.objects.get(id=1))

Serviceを保存して、IDが割り振られてからじゃないとManyToManyFieldの保存はできません。Djangoも多対多のリレーションをサポートするために中間テーブルを作成してくれます。この例ですと、「service_servicecategory」というテーブルがこっそり作られています。

その中間テーブルにServiceCategoryとServiceの関連性を保存するために、新しく登録されたServiceのIDが必要なんですね。

で、削除するには

_service.servicecategory.remove(ServiceCategory.objects.get(id=1))

と書きます。関連する多を全部まとめて一気に消す、とかクエリセットを使って消す、とかもできるのかもしれませんが、まだ試してないです。

もうちっとDjangoを使いこなせるようになりたいもんです。

Python2.5、Django1.1

Tags: ,

PythonでファイルをZIPする

2010-12-15
このエントリーをはてなブックマークに追加

以前RubyでもZIPする方法を書きましたが、今度はPython版です。

基本的にRubyの時と同じく、先にzipファイルを生成してそこに次々とファイルを追加していく、という流れになります。やはり、フォルダの追加はできず、これは再帰的にファイルを追加していくことでフォルダ構造を維持するしかないみたいです。

import zipfile

_zip = zipfile.ZipFile(‘zipファイル名’, ‘w’, zipfile.ZIP_DEFLATED)
_zip.write(zipするファイル名)
_zip.close()

簡単ですね。

wで新規作成、aで既存のzipに追加です。その次のオプションは「zipfile.ZIP_STORED」だと複数のファイルを固めるだけ。「zipfile.ZIP_DEFLATED」だと固めて圧縮です。

Tags:

xml署名の実装にハマった

2010-12-15
このエントリーをはてなブックマークに追加

GoogleAppsで独自のログイン認証をしようとしたりすると、SAMLを使う必要があります。で、さらにぶんなげるxmlにはデジタル署名を加えてやら無いといけないのです。

これはxmlsec、xmlsec-opensslをrpmでインストール(yumだと入らなかった)してやれば済むだろうと簡単に考えていたのですが、そうはいきませんでした。

xmlsecに関しては問題なかったのですが、

Error: unable to load xmlsec-openssl library. Make sure that you have
this it installed, check shared libraries path (LD_LIBRARY_PATH)

と、「xmlsec-OpenSSLがみつかんねーYO!」と怒られてしまうわけです。インストールしたっちゅーねん!

現在の環境はCentOS5.5の64bit。/usr/lib64にパスを通しても変わらず、悶々としていたところ、


libxmlsec1-openssl.so.1

ん?rpmって普段使わないからわかんないんだけど、.soじゃないの?「libxmlsec1-openssl.so」ってシンボリックリンクつくってみるか。うぉぉぉぉ、うごいたぁぁぁぁ!

な感じでした。

結局、

  1. xmlsec、libxslt、xmlsec1-openssl、それぞれのdevelをrpmでインストール(ソースだとlibxml2のバージョンでうるさい)。
  2. /usr/lib64にパス通す。
  3. libxmlsec1-openssl.soっていうシンボリックリンクつくる。

だけでした。

半日悩んだ。。。

Tags: