Django与网址不匹配

时间:2014-01-01 04:49:04

标签: regex django django-urls

我一直在研究一个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不匹配我的网址,任何帮助都表示赞赏。

2 个答案:

答案 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()执行以下操作:

     
      
  1. 如果用户未登录,请重定向到settings.LOGIN_URL,在查询字符串中传递当前绝对路径。例:   /帐户/登录/?下一= /轮询/ 3 /.
  2.   
  3. 如果用户已登录,请执行正常视图
  4.         

    [...]请注意,如果您没有指定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'以指向你自己的视图。现在这在文档中没有提到,但它是有道理的,并且查看默认的管理模板,您可以看到这是正在使用的命名空间。

这对你有意义吗?