Пример индекса карты сайта Django

У меня есть следующие отношения моделей:

class Section(models.Model):
    section = models.CharField(max_length=200, unique=True)
    name = models.CharField(max_length=200, blank = True)


class Article (models.Model):
    url = models.CharField(max_length = 30, unique=True)
    is_published = models.BooleanField()  
    section = models.ForeignKey(Section)

Мне нужно создать карту сайта для статей, которая содержит файлы карты сайта для разделов. Я читал документацию по django здесь http://docs.djangoproject.com/en/dev/ref/contrib/sitemaps/

Но не удалось найти ответ, как я могу:

  1. Определите класс карты сайта в этом случае
  2. Как я могу передать параметры раздела в файл URL (как это объясняется в документах)
  3. Откуда я могу получить {'sitemaps': карты сайта}, если я определил карту сайта как класс python в другом файле в приложении

person Oleg Tarasenko    schedule 08.09.2009    source источник
comment
Ваш вопрос вообще не ясен. 1. Определите его, как описано в документации. Что тебе непонятно? 2. Какие параметры? Какой файл URL - вы имеете в виду urls.py? Это не имеет ничего общего с картой сайта. 3. Вы импортируете его, как и любой другой код, который вы определяете в другом файле.   -  person Daniel Roseman    schedule 08.09.2009
comment
Но для создания карты сайта раздела мне нужно реализовать фильтр. Что-то вроде этого: Acrticle.objects.filter(section = Section.objects.get(section = section)) Не знаю, где мне реализовать фильтр   -  person Oleg Tarasenko    schedule 08.09.2009


Ответы (3)


Если я правильно понимаю, вы хотите использовать индекс карты сайта, который будет указывать на отдельные файлы XML карты сайта для каждого раздела.

Django поддерживает эту функцию, предоставляя отдельное представление карты сайта. для индексных файлов Sitemap.

Раньше не использовал эту функцию, но что-то вроде следующего, вероятно, сработает в вашем случае.

### sitemaps.py
from django.contrib.sitemaps import GenericSitemap
from models import Section

all_sitemaps = {}
for section in Section.objects.all():

    info_dict = {
        'queryset': section.article_set.filter(is_published=True),
    }

    sitemap = GenericSitemap(info_dict,priority=0.6)

    # dict key is provided as 'section' in sitemap index view
    all_sitemaps[section.name] = sitemap

### urls.py
from sitemaps import all_sitemaps as sitemaps

...
...
...

urlpatterns += patterns('',
        (r'^sitemap.xml$', 'django.contrib.sitemaps.views.index', {'sitemaps': sitemaps}),
        (r'^sitemap-(?P<section>.+)\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}),
)
person vinilios    schedule 08.09.2009

Django==2.2
Python==3.6

Вот лучший и простой способ использовать индекс карты сайта в Django, установить django.contrib.sitemaps в проекте, добавив его в INSTALLED_APPS из settings.py. Напишите файл sitemaps.py в своих приложениях и определите нужные классы. Пример расширения django.contrib.sitemap.Sitemap в классе карты сайта StaticViewSitemap для статических URL-адресов, убедитесь, что ваш статический URL-адрес имеет имя для поиска reverse (получение URL-адреса из имени URL-адреса)

# app/sitemap.py

from django.contrib import sitemaps
from django.urls import reverse

class StaticViewSitemap(sitemaps.Sitemap):
    priority = 0.6
    changefreq = 'monthly'

    def items(self):
        # URLs names
        return ['index', 'aboutus', 'ourstory',]

    def location(self, item):
        return reverse(item)

Импортируйте все карты сайта в urls.py, импортируйте карту сайта и индекс из django.contrib.sitemaps.views, затем создайте словарь с картами сайта.

# urls.py

from django.contrib.sitemaps.views import sitemap, index
from app.sitemaps import StaticViewSitemap

# add as many as sitemap you need as one key
sitemaps = {
    "static" : StaticViewSitemap,
}
urlpatterns = [

    # sitemap.xml index will have all sitemap-......xmls index
    path('sitemap.xml', index, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.index'),

    # sitemap-<section>.xml here <section> will be replaced by the key from sitemaps dict
    path('sitemap-<section>.xml', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
]

Здесь у вас будет две карты сайта: 1. sitemaps.xml 2. sitemaps-static.xml Запустить URL-адрес открытия сервера: http://localhost:8000/sitemap.xml

<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <sitemap>
        <loc>http://127.0.0.1:8000/sitemap-static.xml</loc>
    </sitemap>
</sitemapindex>

Django автоматически создал индекс карт сайта, теперь открытых URL: http://127.0.0.1:8000/sitemap-static.xml

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>http://localhost:8000/</loc>
        <changefreq>monthly</changefreq>
        <priority>0.6</priority>
    </url>
    <url>
        <loc>http://localhost:8000/about-us</loc>
        <changefreq>monthly</changefreq>
        <priority>0.6</priority>
    </url>
    <url>
        <loc>http://localhost:8000/our-story</loc>
        <changefreq>monthly</changefreq>
        <priority>0.6</priority>
    </url>
</urlset>
person itsmnthn    schedule 19.10.2019

Для меня принятый ответ влиял на скорость цикла разработки и тестирования, поскольку он заставлял python manage.py команды работать медленнее - у меня было немного больше работы в БД, чем в этом примере.

Вот изменения, которые я внес для смягчения последствий (адаптировано к примеру). Еще не испытал его в бою, но, похоже, это помогает (Python3):

### sitemaps.py

class SitemapLookup():
    """
    Instantiated class replaces the dictionary of {'sitemap-section': Sitemap} for urls.py
    Speeds up application load time by only querying the DB when a sitemap is first requested.
    """

    def __init__(self):
        self.sitemaps = {}

    def __iter__(self):
        self._generate_sitemaps_dict()
        return self.sitemaps.__iter__()

    def __getitem__(self, key):
        self._generate_sitemaps_dict()
        return self.sitemaps[key]

    def items(self):
        self._generate_sitemaps_dict()
        return self.sitemaps.items()

    def _generate_sitemaps_dict(self):
        if self.sitemaps:
            return
        for section in Section.objects.all():
            info_dict = {
                'queryset': section.article_set.filter(is_published=True),
            }
            # dict key is provided as 'section' in sitemap index view
            self.sitemaps[section.name] = GenericSitemap(info_dict, priority=0.6)



### urls.py
from sitemaps import SitemapLookup

...
...
...

sitemaps = SitemapLookup()

urlpatterns += patterns('',
        (r'^sitemap.xml$', 'django.contrib.sitemaps.views.index', {'sitemaps': sitemaps}),
        (r'^sitemap-(?P<section>.+)\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}),
)
person whp    schedule 01.05.2017