Posted at 2012-03-26 22:09:55 under テクノロジ (by key)

SSL通信を行うサイトを作ったりなんかしています。

django + fastcgiプロセスの組み合わせでリダイレクトする処理を確認していたところ、 アプリケーションがプロトコルスキームを認識出来ずにhttp://〜にリダイレクトされる問題がありました。

最初はアプリケーションが固定値でhttp://〜と出力しているのかと思い、 自分が書いた部分のコードやサードパーティのライブラリを含めて調査しまくった結果、 どうやらfastcgiプロセスがプロトコルをハンドリング出来ていないようでした(pdb埋め込んで追いかけまくった)。

で、ダメ押しでnginx fastcgi sslなどでググりまくって得た回答は nginxのコンフィグを適切に設定しないさい というものでした。

参考: FastCGI application behind NGINX is unable to detect that HTTPS secure connection is used

というわけで、以下のようなコンフィグを書いたところ、きちんと動くようになりました。

server {
    listen 443;

    # 省略
    location / {
        include fastcgi_params;
        fastcgi_pass 127.0.0.1:8083;
        fastcgi_pass_header Authorization;
        fastcgi_params HTTPS on;
        fastcgi_intercept_errors off;
    }
}

djangoのビュー関数が処理するrequestオブジェクト(内部オブジェクトを失念してしまったけどwsgi関連?)には アプリケーション実行時の各種環境変数が含まれていますが、この中にHTTPSというキーがありプロトコル判別にはその値を利用しています。 SSLアクセス時には、ウェブサーバ側で強制的に値を突っ込むことで解決することが出来るというわけですね。

というわけで久々のエントリは備忘録でした。

Tags: django, python
Posted at 2011-11-18 20:45:24 under テクノロジ (by key)
  • Python 2.6 / Python 2.7の違い
  • timedeltaにtotal_secondsがない
  • Decimalにfloatを渡せる
  • django-south
  • 同じマイグレーションに対して複数回依存(depends_on)があると「テーブルがもうある」というエラー

ハマったハマった…。

Tags: django, python
Posted at 2011-08-10 00:02:08 under テクノロジ (by key)

UPDATE 2012/1/21

こちらのブログエントリは内容が古いものになりました。 2012年11月以降のdjango-mongodb-engineでDjango 1.3のデータベースオペレータに対応したので、特別な対応なくsouthと連携できます。 ( このへんの , パッチ


Southを利用したくて色々調べていたんですが、 純正SouthをDjango MongoDB Engineと一緒に使うと次のようなエラーが出ます。:

There is no South database module for your database backend south.db.None.
Please either choose a supported database, check for SOUTH_DATABASE_ADAPTER[S] settings,
or remove South from INSTALLED_APPS

その時のsettings.pyはこんなかんじ(一部抜粋):

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'django.db',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
        },
    'mongodb': {
        'ENGINE':'django_mongodb_engine',
        'NAME':'dummy',
        'OPTIONS': {
            'slave_okay':True,
        },
        'SUPPORTS_TRANSACTIONS': False,
       },
   }

southはDATABASES.iteritem()を総ナメしてENGINE属性があればマイグレーションが必要なデータベースとして認識するようです。 SOUTH_DATABASE_ADAPTERSへの記載は、DATABASESに登録されているデータベースで、 south上のどのデータベースドライバを利用するかを設定するものでした。 対応しているデータベースはsouth.db.engine_modulesにまとめられています。

で、 DATABASES['mongodb']['ENGINE'] = 'django_mongodb_engine' が設定されているとき、 engine_modulesに記載が無くsouth.db.Noneが参照されるため、 python manage.py syncdb 実行時にエラーが出力されて停止していまします。

south本体に手を入れるのは本意ではなかったのですが、手を入れないと直らなそうだったので パッチを書いてみました 。 DATABASESに書いてあっても、SOUTH_DATABASE_ADAPTERSに記載がなければ無視するような仕様です。

つたない英語でpull-requestを送ってみましたが、良ければ取り込まれるだろうし、ダメならそのままかなと。 ま、手元では上手くいってるのでよしとします。

Tags: django, mongodb
Posted at 2011-02-22 16:25:24 under テクノロジ (by key)

MyBike.JPを支えるシリーズ第n回目。

DjangoでRSSフィードを作るときに条件指定したかったんだけどやり方が分からなくて、 いろいろ調べてたらDjango 1.2からnew style feedというやつを使うと簡単にできそう。で、早速使ってみた。

Continue reading
Posted at 2011-01-15 01:40:29 under テクノロジ (by key)

MyBike.JPを支える技術シリーズ。

DjangoにMongoDBをインテグレーションするライブラリはいくつかあって、 MyBike.JPではdjango-mongodb-engineを採用しています(セッションストレージに mango を使ってたりしますが、これはまた別の機会に)。

MongoDBをスキーマレスのデータベースとして利用したいこともあって調べていたのですが、 django-mongodb-engineはDjangoのデータベースフィールド拡張が提供されているのみで、 ドキュメント指向データベースとして使うことは難しそうでした。また、GridFSのサポートもあります。

一方、django-mongokitではドキュメント指向データベースとして取り扱えますが、 GridFSのサポートがありません。

この辺り(自分が)混乱しそうなので、マトリクスにメモっておきます。

solution GridFS support Document Extended Model Field
django-mongodb-engine yes no yes
django-mongokit no yes no

django-mongodb-engineでの拡張モデルフィールド例:

class Post(models.Model):
    title = models.CharField()
    tags = SetField(default=set()) # このへんと
    ratings = ListField(models.IntegerField(), ordering=optional_ordering) # このへん

django-mongokitのドキュメントオブジェクト例:

import datetime
from django_mongokit import connection
from django_mongokit.document import DjangoDocument

# Create your models here.
class Talk(DjangoDocument):
    collection_name = 'talks'
    structure = {
        'topic': unicode,
        'when': datetime.datetime,
        'tags': list,
        'duration': float,
    }

    required_fields = ['topic', 'when', 'duration']

    use_dot_notation = True

connection.register([Talk])

GridFSとDocumentオブジェクトを使いたい!という場合には2つを組み合わせて使う必要がありますが、 ニーズが満たせればよいのでとりあえず併用することになりそうです…たぶん。