我正在尝试为每个用户创建一个文件夹来放置他们的项目。因此,他们的文件将包含路径..\project\id\filename
,id
是用户id
和{{1}是文件的名称。现在使用filename
中upload_to
(instance
和filename
}允许的参数,我意识到Filefield
将是instance.id
和路径该文件将为None
而不是..\project\None\filename
。
现在阅读Django documentation upload_to我看到了这个:
在大多数情况下,此对象不会保存到数据库中 但是,如果它使用默认的AutoField,它可能还没有 主键字段的值。
我的解释是创建新记录并且..\project\id\filename
没有同时实例化,也就是说,当我在user_directory_path
模型上调用create
时,Project
将是instance.id
。我现在的问题是,有办法解决这个问题吗?虽然我看到None
很方便,但对于我正在做的动态路径来说并不一定方便。我正在考虑创建记录,然后在更新中添加文件路径,但我正在寻找一种可以一步保存所有内容的方法。
upload_to
当表单通过验证时,这是models.py
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'project/{0}/{1}'.format(instance.user.id, filename)
class Project(models.Model):
email = models.ForeignKey(User,
to_field="email",
max_length=50
)
title = models.CharField(max_length=100)
date_created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
file = models.FileField(upload_to=user_directory_path, validators=[validate_file_type], null=True)
。请注意views.py
之前调用user_directory_path
。
create
答案 0 :(得分:2)
如果如你所说,你想在文件路径中使用的id是用户的id,而不是Project的id ..那么没有问题因为用户已经存在正在保存项目。由于email
是User
的外键,您只需执行以下操作:
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'project/{0}/{1}'.format(instance.email.id, filename)
但是我会指出,在Django的做事方式中,创建一个名为email
的字段是User
的外键实际上非常令人困惑。数据库中的字段将被称为email_id
..并且模型字段的值将返回User
的实例..而不是实际的电子邮件地址,即使电子邮件地址是&#39;存储在列中。要获取电子邮件地址,您需要执行以下操作之一:
myproject.email.email
myproject.email_id
两者都不是很清楚。因此,除非您有充分的理由这样做,否则应调用字段user
并删除to_field='email'
。允许Django通过id
加入表,这是默认行为。
然后,如果您需要用户电子邮件地址,您可以随时通过
获取 myproject.user.email
奖金是,如果用户更改了他们的电子邮件地址,它将随处更改,您不必依赖级联更新来修复所有外键。
相信我,在使用Django时你想通过id
(默认)做ForeignKey,除非有原因...
答案 1 :(得分:1)
一个简单的解决方案是保存没有文件的对象,然后像这样保存文件
email = request.user.email
title = request.POST.get('title', '')
file = request.FILES['file']
filename = file.name
instance = Usermie.objects.get(email=request.user.email)
# Save to model
user_directory_path(instance=instance, filename=filename)
project = Project.objects.create(title=title)
project.file = file
project.save()