Docker-mailman: Удалите example.com как САЙТ по умолчанию в django

Созданный на 21 апр. 2017  ·  9Комментарии  ·  Источник: maxking/docker-mailman

Прямо сейчас, когда появляется экземпляр, сайт по умолчанию устанавливается на example.com (по какой-то причине).

Измените это или добавьте инструкции по изменению идентификатора сайта на фактический используемый домен.

bug documentation web

Все 9 Комментарий

Что еще хуже, если я удалю example.com из списка сайтов, я получаю «Ошибка сервера (500)», и установка становится невозможной.

Вот что в логах mailman-web:

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 39, in inner
    response = get_response(request)
  File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python2.7/site-packages/postorius/views/list.py", line 593, in list_index
    'domain_count': len(choosable_domains)})
  File "/usr/local/lib/python2.7/site-packages/django/shortcuts.py", line 30, in render
    content = loader.render_to_string(template_name, context, request, using=using)
  File "/usr/local/lib/python2.7/site-packages/django/template/loader.py", line 68, in render_to_string
    return template.render(context, request)
  File "/usr/local/lib/python2.7/site-packages/django/template/backends/django.py", line 66, in render
    return self.template.render(context)
  File "/usr/local/lib/python2.7/site-packages/django/template/base.py", line 206, in render
    with context.bind_template(self):
  File "/usr/local/lib/python2.7/contextlib.py", line 17, in __enter__
    return self.gen.next()
  File "/usr/local/lib/python2.7/site-packages/django/template/context.py", line 236, in bind_template
    updates.update(processor(self.request))
  File "/usr/local/lib/python2.7/site-packages/django_mailman3/context_processors.py", line 33, in common
    context["site_name"] = get_current_site(request).name
  File "/usr/local/lib/python2.7/site-packages/django/contrib/sites/shortcuts.py", line 15, in get_current_site
    return Site.objects.get_current(request)
  File "/usr/local/lib/python2.7/site-packages/django/contrib/sites/models.py", line 65, in get_current
    return self._get_site_by_id(site_id)
  File "/usr/local/lib/python2.7/site-packages/django/contrib/sites/models.py", line 35, in _get_site_by_id
    site = self.get(pk=site_id)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py", line 385, in get
    self.model._meta.object_name
DoesNotExist: Site matching query does not exist.

@ulrith Да, вам нужно изменить значение по умолчанию SITE_ID в настройках Django на любой сайт, который вы используете.

По умолчанию значение 1 в контейнере settings.py соответствует example.com.

Вы должны изменить его на 2, что, как я полагаю, будет указывать на ваш домен в settings_local.py . Вы можете добавить следующее:
SITE_ID=2

@maxking Было бы лучше, если бы я мог заменить example.com моим фактическим доменом какой-нибудь командой, как я упоминал в этом комментарии . Или с помощью sql-запроса в контейнере базы данных ... Можете ли вы помочь?

@ulrith Да, из командной строки Django вы попадете в REPL на Python, где вы сможете делать все, что захотите, даже с производственной базой данных ;-)

maxking<strong i="7">@mailman</strong>:~$ docker exec -it mailman-web python manage.py shell
Python 2.7.13 (default, Jun 21 2017, 18:14:15) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.db import models
>>> from django.contrib.sites.models import Site
>>> Site.objects.all()
<QuerySet [<Site: lists.araj.me>]>
>>> Site.objects.create(name='Random Domain', domain='mail.araj.me')
<Site: mail.araj.me>
>>> Site.objects.all()
<QuerySet [<Site: lists.araj.me>, <Site: mail.araj.me>]>
>>> for each in Site.objects.all():
...     print(each.domain, each.id)
... 
(u'lists.araj.me', 2)
(u'mail.araj.me', 3)

Если вам нужно узнать больше об этом, вот ссылка на фреймворк Django Sites.

@maxking На самом деле я не знаком с Python. Не могли бы вы дать мне фрагмент кода (в идеале, один лайнер), который заменит Site: example.com на Site: mydomain.tld для недавно установленного Mailman 3?

Итак, как оказалось, Django сам создает сайт по умолчанию examples.com , и нет никакого способа остановить это поведение.

Итак, вот ваши варианты, если вы хотите создать новый веб-сайт во время запуска.

  • «Правильный» способ сделать это - использовать фикстуры Django. Приспособления позволяют загружать жестко закодированные данные в базу данных для любых целей. Итак, вы вручную создаете файл, сериализованный как JSON, YAML или XML, и запускаете команду: python manage.py loaddata <nameoffixture> и django загружает эти данные в базу данных. Например:

Приведенный ниже файл сохраняется в fixtures/gen_site.yaml :

- model: sites.Site
  pk: 100
  fields:
    domain: gmail.com
    name: Google

Затем вы запускаете python manage.py loaddata gen_site и ваш сайт создается автоматически. Затем вы меняете SITE_ID=100 на settings_local.py и все должно работать!

Однако сделать это прямо сейчас с контейнерами, вероятно, сложно, поскольку нет простого способа фактически запускать пользовательские команды при запуске (также называемые точкой входа в терминологии Docker). Я открыл новый выпуск №61, чтобы отследить эту проблему.

  • Второй вариант для вас - запустить эту команду вручную:
python manage.py shell -c "from django.contrib.sites.models import Site; mysite,_=Site.objects.get_or_create(id=101, name='mysite.tld', domain='mysite.tld'); print(mysite.id, mysite.name)"

Обратите внимание, что приведенная выше команда предназначена для django, поэтому вам нужно добавить docker-compose exec -T mailman-web перед указанной выше командой.
Эта команда создаст новый сайт с именем mysite.tld . Он также распечатает id который затем вам нужно будет поместить в SITE_ID=101 и перезапустить экземпляр Django, чтобы это вступило в силу. Эта команда не завершится ошибкой, если сайт уже существует в базе данных.
Я бы сказал, что это также не лучший способ сделать это, потому что, во-первых, вам нужно перезапустить контейнер, чтобы это вступило в силу (только в первый раз, но это так же плохо), а во-вторых, нет возможности автоматически редактировать settings_local.py чтобы отразить новый SITE_ID без ручного вмешательства, если, конечно, вы не напишите какую-нибудь магию sed или awk .

  • Третий вариант - просто отредактировать домен example.com и обновить его до любого домена, который вы хотите.
python manage.py shell -c "from django.contrib.sites.models import Site; Site.objects.filter(domain='example.com').update(name='My Site', domain='mysite.tld')"

Это не потребует каких-либо изменений, но в моем локальном тестировании я обнаружил, что отображаемое имя вверху не изменится, если я не перезапущу сервер Django, и это потребуется только в первый раз. На мой взгляд, это лучший вариант после первого, который я хочу добавить в образы контейнеров.

@maxking Последний вариант работает как шарм! Спасибо

Должно быть решено.

Переменная среды DEFAULT_FROM_DOMAIN теперь также заменяет домен example.com по умолчанию.

Однако описание не изменяется и может быть изменено на сайте администратора Django.

Исправлено в # 95

Была ли эта страница полезной?
0 / 5 - 0 рейтинги