Ответ 1
50k это не хардкорный параметр.:)
Вы можете использовать этот класс вместо django.contrib.sitemaps.GenericSitemap
class LimitGenericSitemap(GenericSitemap):
limit = 2000
Я реализовал простой класс sitemap, используя django default sitemap app. Поскольку это заняло много времени, я добавил ручное кэширование:
class ShortReviewsSitemap(Sitemap):
changefreq = "hourly"
priority = 0.7
def items(self):
# try to retrieve from cache
result = get_cache(CACHE_SITEMAP_SHORT_REVIEWS, "sitemap_short_reviews")
if result!=None:
return result
result = ShortReview.objects.all().order_by("-created_at")
# store in cache
set_cache(CACHE_SITEMAP_SHORT_REVIEWS, "sitemap_short_reviews", result)
return result
def lastmod(self, obj):
return obj.updated_at
Проблема заключается в том, что memcache допускает только макс. 1MB-объект. Это было больше, чем 1 МБ, поэтому сохранение кэша не удалось:
>7 SERVER_ERROR object too large for cache
Проблема заключается в том, что у django есть автоматизированный способ решения, когда он должен делить файл sitemap на небольшие. Согласно документам (http://docs.djangoproject.com/en/dev/ref/contrib/sitemaps/):
Вам следует создать индексный файл, если один ваших файлов Sitemap содержит более 50 000 URL-адрес. В этом случае Django будет автоматически разбивать карту сайта, и индекс будет отражать это.
Как вы считаете, лучший способ включить кэширование sitemaps? - Взлом в каркасе django sitemaps, чтобы ограничить один размер карты сайта, скажем, 10 000 записей, как лучшая идея. Почему было выбрано 50 000 человек? Совет Google? случайное число? - Или, может быть, есть способ разрешить memcached хранить более крупные файлы? - Или, возможно, сохраненные карты, файлы Sitemap должны быть доступны как статические файлы? Это означало бы, что вместо кэширования с memcached мне пришлось бы вручную сохранять результаты в файловой системе и получать их оттуда в следующий раз, когда запрашивается карта сайта (возможно, ежедневная очистка каталога в задании cron).
Все это кажется очень низким уровнем, и мне интересно, существует ли очевидное решение...
50k это не хардкорный параметр.:)
Вы можете использовать этот класс вместо django.contrib.sitemaps.GenericSitemap
class LimitGenericSitemap(GenericSitemap):
limit = 2000
Предполагая, что вам не нужны все эти страницы в вашей карте сайта, а затем ограничение ограничения для получения размера файла будет работать нормально, как описано в предыдущем ответе.
Если вам нужна очень большая карта сайта и вы хотите использовать memcached, вы можете разделить содержимое на несколько кусков, сохранить их под отдельными ключами и затем снова скомпоновать их на выходе. Чтобы сделать это более эффективным, Memcached поддерживает возможность одновременного получения нескольких ключей, хотя я не уверен, поддерживает ли этот клиент django эту возможность.
Для справки ограничение 1 МБ - это свойство memcached для хранения данных: http://code.google.com/p/memcached/wiki/FAQ#What_is_the_maximum_data_size_you_can_store?_(1_megabyte)
У меня на моем сайте около 200 000 страниц, поэтому я должен был иметь индекс, несмотря ни на что. Я закончил работу над этим взломом, ограничив карту сайта 250 ссылками, а также реализовал кеш файл.
Основной алгоритм таков:
Конечным результатом является то, что в первый раз запрашивается карта сайта, если она завершена, она сгенерирована и сохранена на диске. В следующий раз, когда он попросил, он просто служил с диска. Поскольку мой контент никогда не меняется, это работает очень хорошо. Однако, если я хочу изменить файл Sitemap, он так же прост, как удаление файлов с диска, и ожидание, когда сканеры возвратятся.
Код для всего этого здесь, если вам интересно: http://bitbucket.org/mlissner/legal-current-awareness/src/tip/alert/alertSystem/sitemap.py
Возможно, это будет хорошим решением для вас.
Вы можете обслуживать файлы Sitemap также в формате gzip, что делает их намного меньше. XML отлично подходит для сжатия gzip. То, что я иногда делаю: создайте файлы (файлы) файла Sitemap в cronjob и визуализируйте их так часто, как это необходимо. Обычно, одного раза в день будет достаточно. Код для этого может выглядеть так. Просто убедитесь, что ваш файл sitemap.xml.gz от вашего корня домена:
from django.contrib.sitemaps import GenericSitemap
from django.contrib.sitemaps.views import sitemap
from django.utils.encoding import smart_str
import gzip
sitemaps = {
'page': GenericSitemap({'queryset': MyModel.objects.all().order_by('-created'), 'date_field': 'created'}),
}
f = gzip.open(settings.STATIC_ROOT+'/sitemap.xml.gz', 'wb')
f.write(smart_str(sitemap(request, sitemaps=sitemaps).render().content))
f.close()
Это должно помочь вам начать.