在Django中get_object_or_404总是返回404
这是我的 urls.py
文件
url(r'^file/(?P<filename>.*)$', 'notendur.views.file', name="file"),
这是我的 views.py
文件
@login_required
def file(request, filename):
file = get_object_or_404(Document, user=request.user, filename=filename)
return sendfile(request, file.docfile.path)
这是我的 models.py
文件
fs = FileSystemStorage(location=settings.UPLOAD_ROOT)
class Document(models.Model):
filename = models.CharField(max_length=255, blank=False, null=False, default="")
upload_path = models.CharField(max_length=255, blank=False, null=False, default="")
user = models.ForeignKey(User, null=False)
docfile = models.FileField(upload_to=_upload_path, storage=fs)
options = models.IntegerField(default=0)
def get_upload_path(self,filename):
return "uploads/"+str(self.user.id) + '/' + str(date.today()) + '/' + filename
我的问题是,尽管文件路径是正确的,但我总是收到404错误。我怀疑是我的 get_object_or_404 函数出了问题。
补充说明:
这些文件实际上在 file/uploads/<primary_key>/<upload_date>/
这个路径下!抱歉之前没有提到。请问什么样的正则表达式可以匹配这种链接呢?
2 个回答
0
如果filename
是正确的,那么看起来user
不匹配。这个视图只允许文件的拥有者访问;这样理解对吗?如果是这样的话,你应该返回一个403错误:
@login_required
def file(request, filename):
file = get_object_or_404(Document, filename=filename)
if file.user != request.user:
return HttpResponseForbidden()
return sendfile(request, file.docfile.path)
假设用户的ID是5,他们尝试访问file/test_file
,这个文件是在2014年6月30日上传的。那么filename == 'test_file'
,匹配的记录应该有以下字段:
filename: "test_file"
upload_path: "uploads/5/2014-06-30/test_file"
user: <User with id: 5>
docfile.path: "uploads/5/2014-06-30/test_file"
这和你在磁盘上或数据库中看到的匹配吗?
0
你可以试试用一个查询集:
queryset = Document.objects.filter(user=request.user, filename=filename)
get_object_or_404(queryset)
你也可以打印一些值,看看能不能找到问题所在:
print request.user
print filename
另外,你在网址中接受空字符串作为文件名(通过使用 *)。为什么不使用 "+" 呢?:
url(r'^file/(?P<filename>.+)$', 'notendur.views.file', name="file"),
如果你需要的话,这里有一些参考资料的列表:
# Regular references:
# . any char
# ^ start of string
# $ end of string
# * 0 or more of preceding
# + 1 or more of preceding
# ? 0 or 1 of preceding
# (?!..) matches when it doesnt match ..
# *? 0 or more, minimal match
# +? 1 or more, minimal match
# {m} exactly m of preceding
# {m,n} between m to n of preceding
# [..] eg. [abc],[a-z],[0-9a-z]
# [^..] matches if doesn't match [..]
# (..) groups what's inside
# (?=..) matches .. but doesn't consume it
# \d [0-9] (decimal digit)
# \D [^0-9] (non-digit)
# \w [a-zA-Z0-9_] (alphanumeric)
# \W [^a-zA-Z0-9_] (non-alphanumeric)
# \s [ \t\n\r\f\v] (whitespace)
# \S [^ \t\n\r\f\v] (non-whitespace)