2014-11-02 25 views
1

我有一堆模型。所有这些型号都有一个方法get_absolute_url和一个字段text。我想像维基百科那样在text字段中建立内部链接。在Django中提到/内部链接

维基百科的页面内部链接只能引用其他页面。我需要链接到我的所有模型。

我可以为内部链接制作一个模式,并将此模式用硬编码的网址替换为网址,但它确实不是一个好主意,因为链接可能会更改。所以如果我可以参考get_absolute_url这将是最好的。

另一种选择是使用模板标签将特定模式更改为链接。

应该怎么做?有没有已经完成的开源项目?

+0

你可以给你的目的一个用例吗?我真的不明白为什么你会想要这个 – doniyor 2014-11-02 20:44:10

+0

像Twitter,Instagram,Facebook和维基百科。将用户指向其他页面,并查看页面上是否有其他页面被提及。 – Jamgreen 2014-11-02 20:54:45

+0

你为什么要把事情搞得如此复杂?只是使用命名的网址,你很好! – doniyor 2014-11-02 20:57:46

回答

2

我想在几天前回答这个问题,我用模板过滤器做了这个。我的链接是相对URL,不是绝对的,但你可以很容易地调整,你也可以调整正则表达式来匹配你喜欢的任何链接标记。

使用过滤器时,链接只能在显示时查看,所以如果您的视图的网址发生了变化,该链接会自动使用reverse()查找进行更新。

我也使用Markdown来处理我的描述字段,所以我让链接返回一个markdown格式的链接而不是HTML,但你也可以调整。如果您使用Markdown,则需要先放置此过滤器。

因此,为了显示与内部链接的描述文本字段,模板会是这样的:(见Django docs on writing your own custom filters有关编写更多的细节和注册过滤器)

{{ entity.description|internal_links|markdown }}

至于具体的过滤器本身,我这样做是这样的:

from django import template 
from django.core.urlresolvers import reverse 
from my.views import * 

register = template.Library() 

@register.filter 
def internal_links(value): 
    """ 
    Takes a markdown textfield, and filters 
    for internal links in the format: 

    {{film:alien-1979}} 

    ...where "film" is the designation for a link type (model), 
    and "alien-1979" is the slug for a given object 

    NOTE: Process BEFORE markdown, as it will resolve 
    to a markdown-formatted linked name: 

    [Alien](http://opticalpodcast.com/cinedex/film/alien-1979/) 

    :param value: 
    :return: 
    """ 
    try: 
     import re 
     pattern = '{{\S+:\S+}}' 
     p = re.compile(pattern) 
     #replace the captured pattern(s) with the markdown link 
     return p.sub(localurl, value) 
    except: 
     # If the link lookup fails, just display the original text 
     return value 

def localurl(match): 
    string = match.group() 

    # Strip off the {{ and }} 
    string = string[2:-2] 

    # Separate the link type and the slug 
    link_type, link_slug = string.split(":") 
    link_view = '' 

    # figure out what view we need to display 
    # for the link type 
    if(link_type == 'film'): 
     link_view = 'film_detail' 
    elif(link_type == 'person'): 
     link_view = 'person_detail' 
    else: 
     raise Exception("Unknown link type.") 

    link_url = reverse(link_view, args=(link_slug,)) 
    entity = get_object_or_404(Entity, slug=link_slug) 
    markdown_link = "[" + entity.name + "](" + link_url + ")" 

    return markdown_link 
+0

我还发布了[djangosnippets.org上的一个版本](https://djangosnippets.org/snippets/10420/),它可以解决markdown格式链接内部的internal_links以及它们自己的问题。 – bobtiki 2014-11-08 23:12:00