【问题标题】:How to search a string with the url patterns in django?如何在 django 中使用 url 模式搜索字符串?
【发布时间】:2012-06-27 18:27:28
【问题描述】:

我想为每个创建的帐户创建一个个人资料页面。一旦创建了用户配置文件,就可以像这样访问

http://example.com/username

但在创建之前,我应该验证该 url 已经可用并且未被现有 url 模式采用。例如:会有一个类似的页面

http://example.com/about

现在“about”不是有效用户。但它是一个有效的 url 模式。我应该能够防止创建名称为“about”的用户。为此,除了检查具有该名称的用户是否已经存在之外,我还需要检查 url 模式。如何做到这一点?

一个简单的方法是为个人资料页面设置一个如下所示的 url 模式: http://example.com/user/username

但我强烈要求拥有如下的个人资料页面 http://example.com/username

【问题讨论】:

  • 你能展示一些你目前用来验证 url 的代码吗?我会说像if 'about' in url: return False 这样的东西可能就足够了,但也许我误解了这个问题。
  • 例如在 urls.py 中,我有 url(r'^admin/', include(admin.site.urls)),现在,视图函数不应该允许创建一个用户名称为“管理员”,但没有使用该名称的现有用户。

标签: python django


【解决方案1】:

您可以简单地尝试将地址解析为视图:

from django.core.urlresolvers import resolve
from myapp.views import user_profile_view

try:
    my_view = resolve("/%s/" % user_name)
    if my_view == user_profile_view:
        # We match the user_profile_view, so that's OK.
    else:
        # oops, we have another view that is mapped on that URL
    # you already have something mapped on this address
except:
    # app doesn't have such path

编辑:

您也可以通过其他方式进行检查:

def user_profile_view(request, user_name):
    # some code here

user_profile_view.name = "User Profile View"

然后上面的检查可能是:

if getattr(my_view, "name", None) == "User Profile View":
    ...

【讨论】:

  • 这行不通!它总是进入例外条件。 :-(
  • 哦,对了。您只需检查由此返回的视图名称
  • url(r'^admin/', include(admin.site.urls)) try: urlresolvers.resolve("/%s" % 'admin') match = "路径已经存在" 除了: match = "doesn't match" 我总是得到'doesn't match'
  • 是的,请参阅我的更新答案。您有一个面向用户的包罗万象的视图处理程序。因此,您只需检查此 URL 是否由用户配置文件视图处理(这意味着通配符匹配),或者它是否由另一个视图处理
  • 它总是去例外条件! urlresolvers.resolve 总是引发异常。
【解决方案2】:

您可以添加自定义表单字段验证。看看这个帖子。 Django and Custom Form validation

raise forms.ValidationError(u'please choose another username') 检查并提出错误。

或者您可以尝试将以下内容设置为您的用户的网址, example.com/user/<username>/

编辑 1: you can use this as a list of all invalid usernames

【讨论】:

    【解决方案3】:

    我认为您无法使用django.core.urlresolvers.resolve 进行检查。请注意,它只检查固定 url 的模式,而不是 url 的可变部分。在您的情况下,您很可能将“用户名”作为传递给视图的可变参数。此模式也将匹配不存在的用户名。所以检查模式不是很好的解决方案。

    更好的方法是在不同的命名空间中分离出静​​态页面或其他页面。例如http://example.com/static/about

    或者您可以为您的网站设置预定义的关键字/保留字词,例如[ "about", ... ] 并在创建用户时根据用户名检查它。

    【讨论】:

      【解决方案4】:

      把你的用户名视图放在urls.py的最后,这样会先检查其他的url规则。

      那么最简单的方法是拥有一个无效用户名列表,用于用户注册验证。

      def clean_username(self):
          INVALID_USERNAMES = ('about', 'admin', 'register', '...')
      
          username = self.cleaned_data['username']
          try:
              user = User.objects.get(username=username)
          except User.DoesNotExist:
              pass
          else:
              raise forms.ValidationError(u'%s already exists' % username )
      
          if username in INVALID_USERNAMES:
              raise forms.ValidationError(u'%s is not a valid username' % username )
      
          return username
      

      【讨论】:

        【解决方案5】:

        首先,用户名的 url 规则:

        url(r'^(?P<username>[-\w]+)/$', 'membership.views.profile', name='profile'),
        

        确保用户名不与现有 url 规则冲突有点困难。

        我通常处理这个问题的方式是为 url 添加唯一性:

        url(r'^user/(?P<username>[-\w]+)/$', 'membership.views.profile', name='profile'),
        

        如果您绝对必须让配置文件的 url 以用户名开头,那么您可以尝试使用以下方法获取 url:https://stackoverflow.com/a/2094270/884453,然后确保用户名对于其他用户名和路由都是唯一的

        编辑

        在我写这篇文章的时候,有人发布了一个很酷的想法,让验证器变得更有意义。

        使用from django.core.urlresolvers import resolve 来检查它的唯一性是一个很好的解决方案

        from django.core.exceptions import ValidationError
        from django.core.urlresolvers import resolve
        
        def validate_unique_resolve(value):
            urlroute = True
            try:
                urlroute = resolve(path, urlconf)
            except urlresolvers.Resolver404:
                urlroute = False
        
            if urlroute != False :
                raise ValidationError(u'%s is a reserved url pattern' % value)
        

        【讨论】:

          猜你喜欢
          • 2012-11-01
          • 1970-01-01
          • 2018-12-07
          • 1970-01-01
          • 1970-01-01
          • 2012-08-30
          • 1970-01-01
          相关资源
          最近更新 更多