我一直在研究一个django网络应用程序(使用Django 1.3),这是一个产品的网络目录,它工作正常,直到我被要求添加自定义管理网站。我完全了解Django管理员网站,但客户端非常老式,而且技术无知,所以我必须制作一个“for dummies”版本管理站点。根urlconf:
from django.conf.urls.defaults import *
from django.views.generic import TemplateView
from store.models import Category
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^^$', TemplateView.as_view(
template_name='homepage.html',
get_context_data=lambda: {
'crumb': 'home',
'category_list':Category.objects.all()
}
),
name='home'),
url(r'^favicon\.ico$', 'django.views.generic.simple.redirect_to', {'url': '/static/img/favicon.ico'}),
url(r'^store/', include('store.urls', app_name='store', namespace='store')),
)
商店应用的urlconf:
from django.conf import settings
from django.conf.urls.defaults import *
from store import views
urlpatterns = patterns ('',
url(r'^category/$', views.get_brands, name='get_brands'),
url(r'^(\w+)/$', views.GalleryView.as_view(), name='gallery'),
url(r'^(\w+)/(\w+)/$', views.GalleryView.as_view(), name='gallery'),
)
和原始观点:
from django.http import Http404
from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView
from store.models import Category, Brand, Product
def get_brands(request):
q = request.GET.get('q')
if q is not None:
category = get_object_or_404(Category, slug__iexact=q)
try:
brands = category.brands.all()
except:
brands = []
template = 'infobox.html'
data = {
'category': category,
'brands': brands,
}
return render( request, template, data )
class GalleryView(ListView):
context_object_name = 'product_list'
template_name = 'store/gallery.html'
def get_queryset(self):
self.category = get_object_or_404(Category, slug__iexact=self.args[0])
try:
brand = Brand.objects.get(slug__iexact = self.args[1])
self.brand_name = brand.name
except:
#no brand is specified, show products with no brand
if self.category.category_products.filter(brand__isnull=True):
#if there are products with no brand, return those
return self.category.category_products.filter(brand__isnull=True)
else:
#if all products have a brand, return the products of the first brand
all = self.category.brands.all()
if all:
brand = all[0]
self.brand_name = brand.name
return brand.brand_products.all()
else:
raise Http404
else:
#brand is specified, show its products
return Product.objects.filter(category=self.category, brand=brand)
def get_context_data(self, **kwargs):
context = super(GalleryView, self).get_context_data(**kwargs)
category = self.category
category_brands = self.category.brands.all()
context['category_list'] = Category.objects.all()
context['category'] = category
context['crumb'] = category.name
context['category_brands'] = category_brands
try:
context['brand'] = self.brand_name
except:
context['brand'] = None
return context
现在,我的自定义管理应用程序在我的本地开发环境中工作正常,但是当我将新的网址和视图添加到prod时, Django似乎与任何新网址都不匹配。原始视图和网址仍然有效,但没有新网址匹配,我只是不断收到404 Not Found错误。
更新后的urlconf:
from django.conf import settings
from django.conf.urls.defaults import patterns, include, url
from django.contrib.auth.decorators import login_required
from store import views
admin_urls = patterns ('',
url(r'^$', login_required(views.AdminIndexView.as_view()), name='admin_index'),
url(r'^add/(\w+)/$', login_required(views.AdminAddView.as_view()), name='admin_add'),
)
urlpatterns = patterns ('',
url(r'^category/$', views.get_brands, name='get_brands'),
url(r'^(\w+)/$', views.GalleryView.as_view(), name='gallery'),
url(r'^(\w+)/(\w+)/$', views.GalleryView.as_view(), name='gallery'),
url(r'^login/$', views.admin_login, name='login'),
url(r'^logout/$', views.admin_logout, name='logout'),
url(r'^logout/success/$', views.admin_logout_success, name='logout_success'),
url(r'^test/', views.test, name='test'),
url(r'^admin/', include(admin_urls, namespace='admin')),
url(r'^ajax/$', views.ajax_request, name='ajax_request'),
)
请注意,即使简单的'/ store / test /'url也不匹配。我不确定为什么Django不匹配我的网址,任何帮助都表示赞赏。
答案 0 :(得分:1)
我不确定发生了什么,因为我的所有模板都使用{%url%}标记链接到其他页面,但我认为我的网址混乱的原因是因为我使用了r'^ (\ w +)/ $'正则表达式,所以它匹配任何单词。我只是将带有(\ w +)规则的urlconfs移动到urls.py的底部,并将它们重构为更具体一点,它们又是金币。
更新后的urlconf:
from django.conf import settings
from django.conf.urls.defaults import patterns, include, url
from django.contrib.auth.decorators import login_required
from store import views
admin_urls = patterns ('',
)
urlpatterns = patterns ('',
url(r'^category/$', views.get_brands, name='get_brands'),
url(r'^(\w+)/$', views.GalleryView.as_view(), name='gallery'),
url(r'^(\w+)/(\w+)/$', views.GalleryView.as_view(), name='gallery'),
url(r'^login/$', views.admin_login, name='login'),
url(r'^logout/$', views.admin_logout, name='logout'),
url(r'^logout/success/$', views.admin_logout_success, name='logout_success'),
url(r'^ajax/$', views.ajax_request, name='ajax_request'),
url(r'^administration/$', login_required(views.AdminIndexView.as_view()), name='admin_index'),
url(r'^administration/add/(\w+)/$', login_required(views.AdminAddView.as_view()), name='admin_add'),
)
答案 1 :(得分:0)
正如您在评论中提到的,删除login_required可以解决问题。以下是django文档对装饰器的看法:
login_required()执行以下操作:
- 如果用户未登录,请重定向到settings.LOGIN_URL,在查询字符串中传递当前绝对路径。例: /帐户/登录/?下一= /轮询/ 3 /.
- 如果用户已登录,请执行正常视图
醇>[...]请注意,如果您没有指定login_url参数,那么您将会这样做 需要将相应的Django视图映射到settings.LOGIN_URL。
换句话说,它会转到您可以在settings.LOGIN_URL中覆盖的默认网址。
现在这就是我认为发生的事情 - 我认为您在此定义了自己的登录信息:
url(r'^login/$', views.admin_login, name='login'),
由于新网址中的login_required指向默认网址,该网址不存在,因此返回404.但是,在其他网址后配置了login_required视图:
url(r'^login/$', views.admin_login, name='login'),
...
url(r'^administration/$', login_required(views.AdminIndexView.as_view()), name='admin_index'),
url(r'^administration/add/(\w+)/$', login_required(views.AdminAddView.as_view()), name='admin_add'),
它奏效了。这是为什么?你没有在这里覆盖LOGIN_URL吗?但是你有点做了 - 因为此时,你重新定义了命名空间'login'以指向你自己的视图。现在这在文档中没有提到,但它是有道理的,并且查看默认的管理模板,您可以看到这是正在使用的命名空间。
这对你有意义吗?