2017-02-12 10 views
14

Обычным способом карта сайта используется в Django является:Карта и объект с несколькими URLs

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])() 

Если количество и имена полей не предопределено, я пошел бы для полностью динамического подхода: Allow модели иметь get_sitemap_urls метод, который возвращает список абсолютных URL-адресов, и используйте Sitemap, который выполняет этот метод. То есть, в самом простом случае, когда вам не нужно иметь доступ к объектам в приоритетных/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

Спасибо! Вы решили работать, но я изменил его, чтобы соответствовать моему проекту, потому что у меня есть переменное количество полей для каждого объекта модели. –

+0

Приятно слышать. Я поправлю ответ на вопрос, как я решаю переменное число случаев ссылок. – Phillip

+0

спасибо еще раз! Я сделал это точно так же, как с объектной функцией и нормальными циклами. вы приближаетесь, выглядит более элегантно. –

 Смежные вопросы

  • Нет связанных вопросов^_^