在生产服务器上,当我尝试编辑/创建对象时,保存失败,返回404。这仅在POST请求中发生,GET请求(加载页面)可以正常工作。 Django是通过cPanel和WSGI部署的,DEBUG为False(尽管即使将其设置为True也无法使用)
我已经将cpanel部署在Django应用中,并在virtualenv中运行。这似乎只发生在使用FileField
进行文件上传的模型中,可以很好地更改/创建其他模型。
模型:
def get_image_path(instance, filename):
name, ext = filename.split('.')
return f'images/{instance.advert_id}/{name}.{ext}'
class AdvertImage(models.Model):
advert = models.ForeignKey(Advert, on_delete=models.CASCADE)
image = models.ImageField(upload_to=get_image_path)
URL conf:
urlpatterns = [
path('i18n/', include('django.conf.urls.i18n')),
] + i18n_patterns(
path('admin/', admin_site.urls),
# ... other views....
prefix_default_language=False
)
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
导航到domain.com/admin/colli/advertimage/1/change/
-页面正确加载。填写表格,点击保存。
应保存模型,并且不会出现404。
其他不使用FileField
的模型,因为所有模型的管理员视图均正常工作
对于DEBUG = True,完整的错误消息为:
Page not found (404)
Request Method: POST
Request URL: http://example.com/admin/colli/advertimage/1/change/
Raised by: django.contrib.admin.options.change_view
Using the URLconf defined in Colli.urls, Django tried these URL patterns, in this order:
i18n/
admin/
[name='home']
advert/<slug:slug> [name='detail']
tagauks [name='admin_list']
tagauks/lisa [name='insert']
tagauks/muuda/<int:pk> [name='edit']
tagauks/kasutaja/<int:pk> [name='user_edit']
tagauks/save_image [name='save_image']
accounts/login/ [name='login']
accounts/logout/ [name='logout']
api/
^media/(?P<path>.*)$
The current path, colli/advertimage/1/change/, didn't match any of these.
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
引起这种情况的视图似乎是change_view
答案 0 :(得分:1)
您是否激活了中间件(Internationalization: in URL patterns)?
# settings.py
MIDDLEWARE = [
...
'django.middleware.locale.LocaleMiddleware'
...
]
答案 1 :(得分:0)
我从来没有深入了解这个问题,但是我已经开发出一种解决方法,可以使表单起作用。
在_get_response(self, request)
中编辑django.core.handlers.base
。将resolver_match = resolver.resolve(request.path_info)
更改为resolver_match = resolver.resolve(request.path)
。
添加此中间件(根据您的实际需求进行调整):
class ImageField404Middleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
if (request.method == 'POST' and request.user.is_superuser and response.status_code == 302
and request.get_full_path().startswith('/pathtoadmin/')):
post_messages = get_messages(request)
for message in post_messages:
if ('was added successfully' in message.message or 'was changed successfully' in message.message
and message.level == message_levels.SUCCESS):
messages.success(request, message.message)
redirect_url = request.get_full_path()
if '_addanother' in request.POST:
redirect_url = re.sub(r'[^/]*/[^/]*/$', 'add/', redirect_url)
elif '_save' in request.POST:
redirect_url = re.sub(r'[^/]*/[^/]*/(\?.*)?$', '', redirect_url)
if '_changelist_filters' in request.GET:
preserved_filters = parse.parse_qsl(request.GET['_changelist_filters'])
redirect_url += '?' + parse.urlencode(preserved_filters)
elif '_continue' in request.POST:
redirect_url_search = re.search(r'((?<=href=)[^>]*)', message.message)
if redirect_url_search:
redirect_url = redirect_url_search.group(0)
redirect_url = re.sub(r'[\\"]*', '', redirect_url).replace('/pathtoadmin/pathtoadmin/', '/pathtoadmin/')
return HttpResponseRedirect(redirect_url)
return response
无论如何都不理想,但目前对我有用。
我认为这些问题至少部分是由ModSecurity Apache引起的。托管服务提供商后来重新配置了此设置后,我遇到了一些问题。
您可以在此处阅读更多详细信息:https://medium.com/@mnydigital/how-to-resolve-django-admin-404-post-error-966ce0dcd39d