この質問とほぼ同じ設定で:実行時に upload_to が決定された Django FileField
class Speaker(models.Model):
user = models.OneToOneField(User, related_name='speaker')
middle_name = models.CharField('Middle Name', max_length=40)
profile_file = models.FileField(upload_to=profile_filename, blank=True, null=True)
def profile_filename(instance, filename):
speaker = instance
return "%s.%s.%s.%s.pdf" % (speaker.user.first_name, speaker.official_middle_initial, speaker.user.last_name, "profile")
エラーが発生します:AttributeError: 'User' object has no attribute 'first_name'
これはかなり前に保存されたオブジェクトであり、アプリケーションの他の場所で使用される値を持つユーザーが確実に存在します。Speaker
ユーザーのプロファイル クラスです。ここでバグに遭遇したような気がしますね。
追加の詳細
ここにいくつかの追加の詳細があります。これはセロリ タスク内で発生しているため、重要な要素である可能性があります。ユーザーをセロリタスクに渡します。get_profile
これは、スピーカー オブジェクトを使用して、関連付けられたプロファイル オブジェクトを取得します。私はスピーカー オブジェクトにファイルを保存しました。
ユーザーオブジェクトのフィールドをリストすると、そこにあるようです:
[2012-08-19 11:52:40,819: WARNING/PoolWorker-5] ['date_joined', 'email', 'first_name', 'groups', 'id', 'is_active', 'is_staff', 'is_superuser', 'last_login', 'last_name', 'logentry', 'password', 'speaker', 'user_permissions', 'username', 'userpasswordresetrequired']
トレースバックは次のとおりです。
[2012-08-19 11:52:40,834: ERROR/MainProcess] Task myapp.tasks.retrieveDocument[a4beb536-76a4-48ea-aaf9-9ca0668f9331] raised exception: 'User' object has no attribute 'first_name'
Traceback (most recent call last):
File "/Users/bobspryn/lohi/Remedy/remedyenv/lib/python2.7/site-packages/celery/task/trace.py", line 212, in trace_task
R = retval = fun(*args, **kwargs)
File "/Users/bobspryn/lohi/Remedy/myapp/tasks.py", line 24, in retrieveDocument
afile.save(filename, content)
File "/Users/bobspryn/lohi/Remedy/remedyenv/lib/python2.7/site-packages/django/db/models/fields/files.py", line 85, in save
name = self.field.generate_filename(self.instance, name)
File "/Users/bobspryn/lohi/Remedy/myapp/models.py", line 37, in w9_filename
return "%s.%s.%s.%s.pdf" % (speaker.user.first_name, speaker.official_middle_initial, speaker.official_last_name, DOCUMENT_W9)
AttributeError: 'User' object has no attribute 'first_name'
アップデート
セロリ内で実行されていることに関係しているようです。変。
アップデート
タスク コードの追加。
@task()
def retrieveDocument(user, documentKey, documentType):
echosign = EchoSign(user=user)
fileData = echosign.getDocumentWithKey(documentKey)
if not fileData:
logger.error('Error retrieving document', exc_info=True)
else:
speaker = user.get_profile()
filename = "%s.%s.%s.pdf" % (user.first_name, user.last_name, documentType)
if documentType == DOCUMENT_TEST:
afile = speaker.test_file
elif documentType == DOCUMENT_PROFILE:
afile = speaker.profile_file
content = ContentFile(fileData)
afile.save(filename, content)
speaker.save()