django - Django 2.0.7。用户尝试上传文件时缺少 url 中的完整路径。它适用于本地环境,但不适用于生产服务器
问题描述
我有一个带有 ImageField 的模型:
class Usr( User ):
idusuario = models.AutoField( primary_key = True )
usuario = models.CharField( blank = False, unique = True, max_length = 50 )
contraseña = models.CharField( blank = False, max_length = 250 )
telefono = models.CharField( max_length = 15, blank = True, null = True )
celular = models.CharField( max_length = 15, blank = True, null = True )
fotografia = models.ImageField( blank = True, null = True, upload_to = 'usuarios' )
depende_de = models.ForeignKey( 'self', on_delete = models.CASCADE, related_name = '+', blank = True, null = True )
def __unicode__( self ):
return self.get_full_name()
def __str__( self ):
return self.get_full_name()
及其形式(一个 ModelForm ):
class RegUsuario( forms.ModelForm ):
class Meta:
model = Usr
fields = [
'usuario',
'contraseña',
'is_active',
'is_superuser',
'first_name',
'last_name',
'email',
'telefono',
'celular',
'fotografia',
'groups',
'depende_de'
]
在视图(vw_usuario.py)中,我有:
@valida_acceso( [ 'usr.agregar_usuarios_usuario' ] )
def new( request ):
if 'POST' == request.method:
frm = RegUsuario( request.POST, files = request.FILES )
if frm.is_valid():
obj = frm.save( commit = False )
obj.username = obj.usuario
obj.set_password( obj.contraseña )
obj.save()
for g in request.POST.getlist( 'groups' ):
obj.groups.add( g )
obj.save()
return HttpResponseRedirect( reverse( 'usuario_ver', kwargs = { 'pk' : obj.pk } ) )
frm = RegUsuario( request.POST or None )
return render( request, 'global/form.html', {
'menu_main' : Usr.objects.filter( id = request.user.pk )[ 0 ].main_menu_struct(),
'footer' : True,
'titulo' : 'Usuarios',
'titulo_descripcion' : 'Nuevo',
'frm' : frm
} )
在 urls.py 中:
urlpatterns = [
...
path( 'usuarios/nuevo/', vw_usuario.new, name = "usuario_nuevo" ),
...
]
如果我在浏览器中访问http://example.com/usuarios/nuevo/我也可以显示表单,然后我填写字段并提交表单,我得到了异常:
Page not found (404)
Request Method: POST
Request URL: http://example.com/usuarios/nuevo/
Raised by: seguridad.mkitsafe.validacion
Using the URLconf defined in example.urls, Django tried these URL patterns, in this order:
...
usuarios/eliminar/<pk>/ [name= usuario_eliminar ]
usuarios/nuevo/ [name= usuario_nuevo ]
usuarios/<pk>/ [name= usuario_ver ]
...
The current path, nuevo/, didn t match any of these.
我不明白为什么 url 被视为nuevo/
而不是usuarios/nuevo/
在我正在设置的表单模板中method = "post"
,enctype="multipart/form-data"
并且action=""
(我也尝试过action="usuarios/nuevo"
和action="http://example.com/usuarios/nuevo/"
)
存在的路径MEDIA_ROOT
并具有足够的权限。
如果我填写 ImageField 字段的表格,就会出现问题。
我注意到,如果我删除模型表单中的字段,一切正常。
seguridad.mkitsafe.validacion 的源代码是:
def valida_acceso( permisos = None ):
url_error = 'seguridad_inicio'
url_autenticacion = 'seguridad_login'
def _valida_acceso( vista ):
def validacion( *args, **kwargs ):
usuario = args[ 0 ].user
if not usuario.is_authenticated:
print_error( "Vista {} negada por autenticación".format( vista.__name__ ), "Exec Info" )
return HttpResponseRedirect( reverse( url_autenticacion ) )
if permisos is None:
return vista( *args, **kwargs )
perms = []
for perm in permisos:
permiso = Permiso.get_from_package_codename( perm )
if( permiso is None ):
print_error( "No se ha encontrado el permiso: " + perm )
else:
perms.append( permiso.perm() )
desc = permiso.descendencia()
for p in desc:
perms.append( p.perm() )
for perm in perms:
p = "{}.{}".format( perm.content_type.app_label, perm.codename )
if usuario.has_perm( p ):
return vista( *args, **kwargs )
print_error( "Vista {} negada por permisos {}".format( vista.__name__, permisos ), "Exec Info" )
return HttpResponseRedirect( reverse( url_error ) )
return validacion
return _valida_acceso
它是一个装饰器,用于验证烫发和身份验证。
如果我删除此装饰器,则异常会更改Raised by
为seguridad.vw_usuario.new
Page not found (404)
Request Method: POST
Request URL: http://example.com/usuarios/nuevo/
Raised by: seguridad.vw_usuario.new
Using the URLconf defined in example.urls, Django tried these URL patterns, in this order:
admin/
...
usuarios/actualizar/<pk>/ [name='usuario_actualizar']
usuarios/eliminar/<pk>/ [name='usuario_eliminar']
usuarios/nuevo/ [name='usuario_nuevo']
usuarios/<pk>/ [name='usuario_ver']
usuarios/ [name='usuario_inicio']
...
The current path, nuevo/, didn't match any of these.
我还注意到,当引发错误并且装饰器处于活动状态时,不会调用装饰器或视图函数。
我还尝试使用脚本复制 MEDIA_ROOT 路径中的文件,并且效果也很好,因此脚本有权访问此路径。
对这个问题有任何评论吗?
解决方案
推荐阅读
- c++ - 如何在子目录中创建文本文件?
- r - 我想根据“08:00:00-20:00:00”内外的最大持续时间分配“白天”和“夜晚”变量
- angular - Angular 7如何在observable中获取http错误的主体(json)
- android - 使用带有参数(MVVM,存储库)的 firestore 查询更新 android livedata
- php - 从mysql表中获取数据并显示
- c# - 如何按长度为 10、0-10、11-20 等对数组进行分组
- asp.net - ASP.net 如何循环遍历 sql server 并更新表格按钮图像?
- c# - 多个网站的通用配置部分
- laravel - Laravel:如何从具有关系的 3 个表中获取数据
- javascript - 如何只关闭打开的 mdDialogs 之一?AngularJs