Slide 1

Slide 1 text

Мульти-­‐доменность   в  Django  проекте   Специально  для   MoscowDjango  Meetup  #7   by  Alexey  Kinyov  [email protected]  

Slide 2

Slide 2 text

Кто  докладывает   •  Алексей  Кинёв,  30  лет,  Москва,  тех.   директор  в  компании  КСАН   •  Опыт  разработки  на  Python/Django  4  года   •  Проекты:   – PCNews.ru,  Qmazi.com,  Gallerza.com   – django-­‐smarter   •  Home  page:   – hmp://05bit.com/rudyryk/  

Slide 3

Slide 3 text

Проблема  /  задача   Single  domain:   hmp://domain.com///     Muls  domain:   hmp://.domain.com//    Single  domain  =>  Muls  domain  

Slide 4

Slide 4 text

Варианты  решения   •  django.contrib.sites   –  стандартно,  но  не  то:  1  домен  ó  1  seyngs.SITE_ID   •  использовать  Middleware   –  звучит  разумно   •  использовать  свой  DNS  /  BIND   –  «бесплатно»  +  полный  контроль,  но  рискованно,   сложно   •  использовать  сторонний  DNS  SAS  с  API   –  проще,  но  за  деньги  

Slide 5

Slide 5 text

Выбранное  решение   Делаем  Middleware   +  PowerDNS.com     BEST  PRACTICE?  Not  sure.   Just  works  J  

Slide 6

Slide 6 text

Пикантные  подробности   Пример  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)! !# ...!

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

Пикантные  подробности   Пример  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  

Slide 9

Slide 9 text

Пикантные  подробности   ! 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  

Slide 10

Slide 10 text

Profit  J   hUp://myblog.qmazi.com/post/20/       /~/myblog.qmazi.com/post/20/       post_view  

Slide 11

Slide 11 text

Слабые  места   1.  Нельзя  использовать  reverse  для   генерации  host-­‐based  адресов   2.  Усложнение  views   Решается  адекватным  набором  u]ls.  

Slide 12

Slide 12 text

Развитие  решения   «Прячем»  служебные  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)! !# ...!  

Slide 13

Slide 13 text

Спасибо!   Вопросы?