]>
<< DjangoでRSSリーダーを作る(1) | main | テクニカルエンジニア(データベース)を明日に控えて >>
現在の状況を整理すると、
タイトル欄に直で日本語を入力→登録される
フィードから日本語の含まれるタイトルを取得→エンコードエラー
エラーメッセージは
UnicodeEncodeError at /admin/sites/site/add/ 'latin-1' codec can't encode characters in position 0-2: ordinal not in range(256)
となっているため、どこかUnicodeにすべき部分がもれているのでしょう。
通常のサーバーでしたら
MySQLのUnicodeColに日本語文字列をセットする問題の自分なりの解決
といった方法でうまくいくのかもしれません。が、僕はさくらの共有サーバーを使っているため、MySQLの設定ファイルなどを直接触ることができません。ODBC接続すらできません…。コメント欄にてデータベース作成時にutf8を指定すれば、という書き込みを頂いたのですがそれも試せそうにありません……。これはMySQLdbかDjango内部でどうにかするしかなさそうです。
Django | Model reference | Executing custom SQL
あたりを参考に、
connection.cursor().execute("SET CHARACTER SET utf8")
なんて送ってみても
OperationalError at /admin/sites/site/add/ (1115, "Unknown character set: 'utf8'")
また、MySQLdb/connection.py内にて文字コードを設定していると思しき変数charsetを'utf8'と固定にし、再インストールしてもエラーがでてしまう。
上のメッセージを読むとかなり嫌な予感がする訳ですが……MySQLのバージョンを調べてみる。
>>> import MySQLdb >>> cnx = MySQLdb.connect(host='mysql**.db.sakura.ne.jp', user='******', passwd='******') >>> cnx.get_server_info() '4.0.27'
MySQL AB :: Unicode and Other Funny Characters :: What 4.0 Did
MySQL 4.0 (and earlier versions) only supported what amounted to a combined notion of the character set and collation with single-byte character encodings, which was specified at the server level. The default was latin1, which corresponds to a character set of latin1 and collation of latin1_swedish_ci in MySQL 4.1.
No information about the character set (and collation) of the data is stored in the table, and there is no support in MySQL 4.0 for converting between character sets. To convert the data to another character set, you would need to change the server's character set, and then use an external tool to convert the data.
A common strategy for applications built using MySQL 4.0 that needed to handle data in multi-byte character encodings (such as UTF-8) that were not supported natively was to simply store the data in VARCHAR fields (or TEXT, CHAR, etc). The application would either ignore the fact that MySQL would simply sort the data incorrectly for strings that weren't really in the character set that the server thought they were, or do the sorting in the application. That strategy worked fine, you just had to handle all of the encoding issues in your application, and you also lost the ability to take full advantage of MySQL's full-text searching.
MySQL4.0は文字コード間の変換をサポートしてないから、サーバー側で設定してね、と書いてあるように見える……。しかしUnicodeをUnicodeとして扱えないにしてもデータの挿入自体はできるようなので、そこでエラーが出るというのはやっぱりどこかがおかしいんでしょう。
結局、エンコードを適当に試した結果、下のようにすると正常にタイトルの取得と挿入ができました。エンコードを行う際にunicode()だとエラーが出ますが、encode('utf-8')だと大丈夫なようです。FeedParserで取得したタイトルの文字コードがutf-8じゃなかったということなんですかね。なんか動いてはいるんですが僕自身理解できてません。
![]()
from django.db import models
import feedparser
# Create your models here.
class Site(models.Model):
title = models.CharField(blank=True, maxlength=100)
rss = models.URLField(blank=False, verify_exists=True, maxlength=100)
last = models.DateTimeField(auto_now_add=True)
def save(self):
if not self.title:
# self.title = unicode(feedparser.parse(self.rss).feed.title)
self.title = feedparser.parse(self.rss).feed.title
self.title = self.title.encode('utf-8')
super(Site, self).save()
def __str__(self):
return self.rss
class Admin:
list_display = ('title', 'rss', 'last')
http://www.panopticon.jp/mt/mt-tb.cgi/66
コメントする