2014-11-02 37 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