ハセテツラボ

生涯一開発屋

Pythonでフォルダ内のファイル一覧を取得する

without comments

用途に合わせて2パターンあります。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os

list = os.listdir(‘/path/to/dir/’)
for file in list:
 print file

この例だと、対象フォルダ内のすべてを列挙します。つまり、サブフォルダも抽出対象ということです。これでいい場合もあるし、いやいやファイルだけ欲しいんだよ、という場合もあるでしょう。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import glob

list= glob.glob(‘/path/to/dir/*.*’)
for file in list:
 print file

上記の例であれば、対象フォルダのファイルだけを抽出します。まぁファイルだけ、とっても「拡張子が付いているもの」、というか名前にドットが付いているものを抽出しています。よって、ドットが付いた名前のフォルダも引っかかりますね。

ふたつめの例で、さらにos.path.isfile(対象)を使ってファイルか否かをチェックすればよいと思います。

Written by ハセテツ

3月 10th, 2010 at 12:55 pm

Posted in Python

Tagged with

qmail+vpopmailの環境でDjangoからメールをSMTP認証で送信する

without comments

vpopmailを使ってqmailでバーチャルドメイン運用している場合、困った問題がひとつあります。vpopmailがCRAM-MD5に未対応なんですね。

まぁMTAとして運用するにはたいして問題ないんですが、Djangoでメール送信しようとすると大問題、DjangoはSMTP認証のときにパスワードをMD5で暗号化してqmailに送っているようです。よって、qmailから「SMTP認証にコケました。」と叱られてしまうわけです。

ので、PLAINでSMTP認証をする方法です。

PythonインストールディレクトリのLibフォルダに「smtplib.py」があるはずです。その562行目付近、

preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]

preferred_auths = [AUTH_PLAIN, AUTH_LOGIN,AUTH_CRAM_MD5]

に変更します。認証の優先順位ですね。優先順位を入れ替えているだけなのでCRAM_MD5が使えなくなるわけでもなく、vpopmailの困った仕様にも対応可能です。

MTA変えただけでメールが送信できなくなり、しかもMUAからは無事に送信で来ちゃっていたのでまったくわからず、一晩悩みました。

Written by ハセテツ

3月 8th, 2010 at 1:40 pm

Posted in Django, Python, Qmail

Tagged with , ,

Pythonで文字列エンコーディング

without comments

例えばWindowsクライアントからアップロードされたCSVとかはたいていShift_JISなわけです。Pythonは基本的にUTF-8(Django使ってるから、というのも大きな理由ですな)なので、そのままだとえらいこっちゃになるわけです。

u”ほげほげ”.encode(‘cp932′,’utf-8′)

cp932(Shift_JIS)からutf-8にエンコードしますよ、という指定です。「文字列.encode(‘utf-8′)」でもいいのですが、それだとエンコード前の文字列エンコーディングは自動判定みたいですね。しょっちゅう「こんな文字列エンコード知らない」ってエラーが出ました。

ので、「~から~にエンコードしてね」ってやさしく説明してあげたほうが確実というわけです。

Written by ハセテツ

3月 3rd, 2010 at 10:48 am

Posted in Python

Tagged with

PythonでDjangoを使ったバッチ処理

without comments

たいていのアプリにバッチは付き物なのですが、DjangoにはRailsでいうところのscript/runnerがありません。

まぁPythonでバッチ書いてそれを叩けばいいのですが、settingsの値とか、モデルデータとか、やっぱり共有したいわけですよ。

# -*- coding: utf-8 -*-
import sys
import os

sys.path.append(“C:/works/Python”)
os.environ['DJANGO_SETTINGS_MODULE'] = ‘hogepj.settings’

from hogepj.app.models import *

_hoge = Hoge.objects.all()
for item in _hoge:
    print item.name

sys.path.appendに書くのはプロジェクトがあるフォルダです。プロジェクトフォルダは含みません。Pythonというフォルダのなかにhogepjというプロジェクトフォルダがある、という前提です。

Railsだと「Railsアプリのバッチを実行する」な感じだったのに対して、Djangoだと「バッチをDjangoアプリの一部として実行する」って感じでしょうか。

環境はPython2.5、Django1.1.1です。

Written by ハセテツ

2月 25th, 2010 at 5:47 pm

Posted in Django, Python

Tagged with ,

PythonでURLエンコードする方法

without comments

GETでクエリを引きずり回す時などに使いますね。後は日本語名称のファイルをクライアントに出力するときでしょうか。2バイト文字の世界の人々には必須の知識ですよね。

import urllib

print urllib.quote_plus(‘ほげほげ’)
print urllib.unquote_plus(‘%82%D9%82%B0%82%D9%82%B0′)

上がエンコード、下がデコード。

ソースコード中に2バイト文字書くときは

u’ほげほげ’

といった感じでuをつけないといけなかったのですが、ここでは不要です。

Written by ハセテツ

2月 15th, 2010 at 10:59 am

Posted in Python

Tagged with

Djangoのformでカスタムバリデーションをする方法

without comments

例えば会員登録とかでパスワードを確認のために2回入力してもらうときとか、両方の値があっているかチェックする必要があります。

Djangoの標準バリデーションだとそこまではやってくれないんですね。

でも、バリデーションのカスタマイズはとっても簡単です。簡単なハズなのに、とってもてこずりました。w

# -*- coding: utf-8 -*-

from django import forms

class RegistForm(forms.Form):
    name = forms.CharField(max_length=100)
    mailadd = forms.EmailField(max_length=100)
    passwd = forms.CharField(min_length=6, max_length=12, widget=forms.PasswordInput(render_value=False))
    passwd_confirm = forms.CharField(min_length=6, max_length=12, widget=forms.PasswordInput(render_value=False))

    def clean_passwd_confirm(self):
        _pswd = self.cleaned_data['passwd']
        _pswd_confirm = self.cleaned_data['passwd_confirm']
        if _pswd!=_pswd_confirm:
            raise forms.ValidationError(u’確認用パスワードが異なります。’)
        else:
            return _pswd_confirm

clean_フィールド名のメソッドが、対象フィールドのバリデーション用メソッドです。self.cleand_dataで値にアクセス、検証してNGならraiseする。OKなら値をそのまま返す。

これだけ!w

Written by ハセテツ

2月 6th, 2010 at 2:51 am

Posted in Django, Python

Tagged with ,

インターネット上でビジネスをするなら必読だと思う本

without comments

特にFREEがお気に入りです。

両方ともクリス・アンダーソンの著作。「ロングテール」というキーワードの生みの親(厳密には違いますが)で、Wiredの編集長ですね。

読んでなにか答えが得られる本ではないと思いますが、インターネット上でビジネスをする、インターネットにかかわる仕事をする人たちにとっては必読の本ではないかと思います。

Written by ハセテツ

1月 29th, 2010 at 10:29 am

Posted in 読書

Pythonで文字列を桁埋め(パディング)

without comments

どの言語でもパディングのエントリ書いてる気がする。

>>> print ‘%(#)05d’%{‘#’:3}

「3」という数字を「0」で桁埋めして「5桁(00003)」にします。

Written by ハセテツ

1月 21st, 2010 at 6:31 pm

Posted in Python

Tagged with

Djangoのテンプレートでカスタムフィルタを使う

without comments

例えばリストをループで複数行書き出す時とかは、奇数行と偶数行で背景の色を分けたかったりします。でも、Django標準だとそんなことできないっぽいんですよね。

ので、カスタムフィルタを使って実装してみました。

  1. アプリケーションディレクトリ(models.pyとかviews.pyが置いてあるトコ)に「templatetags」というフォルダを作成。
  2. そのフォルダの中に「__init__.py」と「hoge.py」を作成。「__init__.py」は白紙。
  3. 「hoge.py」に以下を記述
    from django import template
    register = template.Library()
    @register.filter(name=’getOddEven’)
    def getOddEven(_val):
        if _val % 2==0:
            return ‘even’
        else:
            return ‘odd’
  4. テンプレートファイル側に{% load hoge %}と記述。
  5. テンプレートのループの中で「{{ forloop.counter|getOddEven }}」と記述すると「odd/even」の文字列が返ってくる。

フィルタの使い方としては、「値|フィルタ」といういつもの書き方とおんなじです。

「forloop.counter」というのはテンプレート内でfor文を使ったときに内部で持っている値です。サンプルを見るとわかりやすいかな。

{% for item in list %}
{{ forloop.counter }},
{% endfor %}

これで、1,2,3,,,,と表示されます。1から始まる序数ですね。「django/template/defaulttags.py」を見ていただくと、他にもいろいろな値を持っています。これは便利。

で、あとはその序数をカスタムフィルタに渡してあげればOKということです。

{% load hoge %}
{% for item in list %}
<p class=”{{ forloop.counter| getOddEven}}”>{{ item }}</p>
{% endfor %}

恐るべしDjango、使いこなすまでの道のりは長い。。。

Written by ハセテツ

1月 19th, 2010 at 6:48 pm

Posted in Django, Python

Tagged with ,

Pythonで文字列を暗号化

without comments

暗号化といいますか、実はMD5のハッシュ値です。

import hashlib
暗号化された文字列=hashlib.md5(‘暗号化する前の文字列’).hexdigest()

これだけです。

ハッシュ関数は一方向要約なので複合はできません(と思っていますが、できるのかなぁ)。

Written by ハセテツ

1月 14th, 2010 at 12:03 pm

Posted in Python

Tagged with