Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Мульти-доменность в Django проекте

Мульти-доменность в Django проекте

Алексей Кинёв

Расскажу о реализации мультидоменности в Django-проекте на примере блоговой платформы Qmazi. Про архитектуру, приемы и немного про безопасность.

Moscow Python Meetup

November 21, 2012
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. Кто  докладывает   •  Алексей  Кинёв,  30  лет,  Москва,  тех.

      директор  в  компании  КСАН   •  Опыт  разработки  на  Python/Django  4  года   •  Проекты:   – PCNews.ru,  Qmazi.com,  Gallerza.com   – django-­‐smarter   •  Home  page:   – hmp://05bit.com/rudyryk/  
  2. Проблема  /  задача   Single  domain:   hmp://domain.com/<blog>/<post>/    

    Muls  domain:   hmp://<blog>.domain.com/<post>/    Single  domain  =>  Muls  domain  
  3. Варианты  решения   •  django.contrib.sites   –  стандартно,  но  не

     то:  1  домен  ó  1  seyngs.SITE_ID   •  использовать  Middleware   –  звучит  разумно   •  использовать  свой  DNS  /  BIND   –  «бесплатно»  +  полный  контроль,  но  рискованно,   сложно   •  использовать  сторонний  DNS  SAS  с  API   –  проще,  но  за  деньги  
  4. Пикантные  подробности   Пример  models.py:     class Channel(models.Model):! !slug

    = models.CharField(max_length=100, unique=True)! !title = models.CharField(max_length=200)! !# ...! ! class Post(models.Model):! !channel = models.ForeignKey(Channel)! !# ...!
  5. Пикантные  подробности   Пример  urls.py     urlpatterns = ('',!

    ! # host based views! url(r'^~/(?P<host>[^/]+)/$',! ! !channel_view),! url(r'^~/(?P<host>[^/]+)/post/(?P<pk>\d+)/$',! ! !post_view),! # ...! )! !
  6. Пикантные  подробности   Пример  views.py:     def post_view(request, host,

    pk):! !# get 'myblog' of 'myblog.qmazi.com'! slug = host.split('.', 1)[0]! !post = get_objects_or_404(Post, channel__slug=slug, pk=pk)! return render(request, 'channel/post.html', {'post': post})! hmp://qmazi.com/~/myblog.qmazi.com/post/20/   host   pk  
  7. Пикантные  подробности   ! class MultiHostMiddleware(object):! def process_request(self, request): !

    # settings.SITE_HOST = 'domain.com’ # main domain! if request.get_host() != settings.SITE_HOST:! ! !request.path = '/~/%s/%s' % (! ! !request.get_host(),! ! !request.path.lstrip('/'))! ! !request.path_info = request.path! The  trick:  подменяем  request.path_info  
  8. Слабые  места   1.  Нельзя  использовать  reverse  для   генерации

     host-­‐based  адресов   2.  Усложнение  views   Решается  адекватным  набором  u]ls.  
  9. Развитие  решения   «Прячем»  служебные  url’ы:   ! def post_view(request,

    host, pk):! !if not settings.DEBUG_HOSTS:! ! !if host != request.get_host():! ! ! !raise Http404! !# ...!   Подключаем  любой  домен:   ! def post_view(request, host, pk):! !# ...! !channel = get_channel_by_host(host) # my utils! !post = get_objects_or_404(Post, channel=channel, pk=pk)! !# ...!