【问题标题】:Django,prepopulated_fieldsDjango,预填充_字段
【发布时间】:2009-08-15 14:45:15
【问题描述】:

我想知道 prepopulated_field 在 ModelAdmin 之外是否可用?

我想创建一个值来自字段标题的 slugfield。

问候, 阿西诺斯

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    我不知道。 我使用 javascript 和 AJAX 做了类似的事情:当标题字段失去焦点时,带有它的 AJAX 请求被发送到您的应用程序中返回一个 slug 的 url。这是javascript:

    <script type="text/javascript">
    Event.observe(window, 'load', function() {
        form = $("post_form");
        title = $('id_title');
        slug = $('id_slug');
        title.observe('blur', getSlug);
    });
    
    function getSlug() {
        var titleText = $F(title);
        ajax = new Ajax.Request("/blog/utils/get-slug", {
            'method': 'get',
            'parameters': {'title': titleText},
            'onSuccess': setSlug
        })
    
    }
    function setSlug(transport) {
        var slugText = transport.responseText;
        slug.value = slugText
    }
    </script>
    

    它使用 Prototype,但您也可以轻松地使用 jQuery 或其他任何东西。 在 Django 方面,这里是 AJAX 请求被定向到的视图以及一些辅助函数:

    def GetSlug(request):
        """This Django view provides a url-friendly slug based on a given post title. 
        It helps avoid primary key violations by creating different slug names 
        for posts with the same title.It is designed to be called by an AJAX 
        request from within the admin interface."""
    
        title = request.GET.get('title', None)
        title = unquote(title)
        if not title:
            return HttpResponseNotFound("")
        result = findSlug(title)
        if not result:
            result = ""
        return HttpResponse(result)    
    
    def findSlug(title):
            title = urlify(title)
            words = title.split('-')
            if len(words) > 5:
                title = "-".join(words[0:5])
                extraWords = words[5:]
            else: 
                extraWords = []
    
            def testSlug(slug):
                try:
                    Post.objects.get(slug=slug)
                except Post.DoesNotExist:
                    return slug
                return False
            #if slug does not already exist, return that
            if testSlug(title):
                return title
            #if title had extra words, add them one at a time and test that
            else:
                for word in extraWords:
                    title = title + "-" + word
                    if testSlug(title):
                        return title
            #if we've run out of words and slug is _still_ not unique, try incrementing: title-2, title-3, etc. 
            incrementor = 2
            while incrementor < 10:
                tempTitle = title + "-%d" + incrementor
                if testSlug(tempTitle):
                    return tempTitle
            #if all else fails, punt to the user
            return None
    
    def urlify(string):
        """This takes a string (say, a post title) and convets it to something url-friendly
    
        >>> title = "I read \"War & Peace\" to-day"
        >>> urlify(title)
        i-read-war-and-peace-to-day
    
        """
        string = string.lower().strip() #remove leading, trailing whitespace
        string = string.replace("&", "and")
        string = re.sub("[^a-z0-9- ]", "", string) #remove non-alphanumeric chars  (except dashes and spaces)
        string = re.sub("\W+", "-", string) #replace whitespace with "-"
        string = re.sub("-{2,}", "-", string) #remove double dahses
        return string 
    

    GetSlug 视图非常努力地返回一些有用但独特的东西,即使在标题可能已经存在于另一条记录的情况下也是如此。

    【讨论】:

      【解决方案2】:

      它不是立即可用的,但是您可以通过在模型中覆盖save() 方法来轻松创建自己的系统。例如。

      def save(self, *args, **kwargs):
          # If there is not already a slug in place...
          if not self.[name-of-slug-field]:
              # Import django's builtin slug function
              from django.template.defaultfilters import slugify
              # Call this slug function on the field you want the slug to be made of
              self.[name-of-slug-field] = slugify(self.[field-to-slugify])
          # Call the rest of the old save() method
          super([model-name], self).save(*args, **kwargs)
      

      您需要更改方括号中的内容以使其与您的模型相关。

      [name-of-slug-field] 是模型中包含实际 slug 的字段(例如,'this-is-slugged')

      [field-to-slugify] 是您要从中构建 slug 的字段(在您的情况下,它可能是 title

      [model-name]是该方法所在模型的名称

      该代码的最后一行是我认为唯一可能复杂的部分,它只是在其位置添加旧的 save() 方法的其余部分,因此当您调用 save() 时,它仍然会物理地将更改提交到数据库。

      显然,这些更改只会在服务器端进行,因此用户不会“看到”它们发生,所以如果你想模拟 Django 管理面板的工作原理(即 slug 自动出现在文本框中slug),你需要合并 mazelife 的 Ajax 代码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-04-04
        • 1970-01-01
        • 1970-01-01
        • 2011-07-11
        • 2022-11-04
        • 2010-10-06
        • 2017-03-27
        相关资源
        最近更新 更多