2017-02-12 55 views
14

正常途徑站點地圖在Django採用的是:地圖和對象與多個URL

from django.contrib.sitemaps import Sitemap 
from schools.models import School 


class SchoolSitemap(Sitemap): 
    changefreq = "weekly" 
    priority = 0.6 

    def items(self): 
     return School.objects.filter(status = 2) 

,然後在學校的模型中,我們定義:

def get_absolute_url(self): 
     return reverse('schools:school_about', kwargs={'school_id': self.pk}) 

在這樣的實現方式我已經一個關於鏈接在sitemap.xml中的一所學校

問題是,我的學校有多個頁面:關於教師,學生和其他人,我希望所有的被渲染是sitemap.xml

這樣做的最佳方法是什麼?

回答

10

您可以用事實items may return anything that can be passed to the other methods of a Sitemap工作:

import itertools 

class SchoolSitemap(Sitemap): 
    # List method names from your objects that return the absolute URLs here 
    FIELDS = ("get_absolute_url", "get_about_url", "get_teachers_url") 

    changefreq = "weekly" 
    priority = 0.6 

    def items(self): 
     # This will return you all possible ("method_name", object) tuples instead of the 
     # objects from the query set. The documentation says that this should be a list 
     # rather than an iterator, hence the list() wrapper. 
     return list(itertools.product(SchoolSitemap.FIELDS, 
             School.objects.filter(status = 2))) 

    def location(self, item): 
     # Call method_name on the object and return its output 
     return getattr(item[1], item[0])() 

如果數字和字段的名稱不是預定的,我會去一個完全動態的方法:允許模型有一個get_sitemap_urls方法返回一個絕對URL列表,並使用執行此方法的Sitemap。也就是說,在最簡單的情況下,您無需訪問priority/changefreq/lastmod方法中的對象:

class SchoolSitemap(Sitemap): 
    changefreq = "weekly" 
    priority = 0.6 

    def items(self): 
     return list(
      itertools.chain.from_iterable((object.get_sitemap_urls() 
              for object in 
              School.objects.filter(status = 2))) 
     ) 

    def location(self, item): 
     return item 
+0

謝謝!您的解決方案正在工作,但是我已經將其更改爲適合我的項目,因爲我爲每個模型對象都有可變數量的FIELDS。 –

+0

好聽。我會修改答案,我將如何解決可變數量的鏈接案例。 – Phillip

+0

再次感謝您!我用對象函數和正常循環以相同的方式創建它。你的做法看起來更優雅。 –