我想通过 2 个 URL 共享单个基于代码的 Django (2.2):foo.domain.ltd
& bar.domain.ltd
。
- on
foo.domain.ltd
:所有 Django URL 都可用 - on
bar.domain.ltd
:只有一些 URL 可用,所有其他 URL 都返回 403 错误
我希望使用站点框架(django.contrib.sites
)来达到这个目标:
- 1个代码库
- 在站点框架中配置的2 个域
- 2 个
gunicorn
具有适当配置的实例:core.settings.foo
和SITE_ID = 1
core.settings.bar
和SITE_ID = 2
- 1
nginx
服务器侦听客户端并将请求转发到适当的gunicorn
实例,具体取决于所xxx.domain.ltd
使用 的
我遇到的问题是站点框架看起来像面向模型:您可以关联models
到一、二(…)sites
。
我尝试根据 设置urls
,sites
但我破坏了./manage migrate
工具......</p>
1)将站点框架设置为我的项目和一个dualsite
应用程序来托管相关代码:
core.settings
:
INSTALLED_APPS = [
# (…)
"django.contrib.sites",
"dualsite.apps.DualsiteConfig",
]
core.settings.foo
:
from core.settings import *
SITE_ID = 1
core.settings.bar
:
from core.settings import *
SITE_ID = 2
dualsite.migration.0001_set_sites
:
from django.db import migrations
def my_sites(apps, schema_editor):
Site = apps.get_model("sites", "Site")
initial_site = Site.objects.get(id=1)
initial_site.domain = "foo.domain.ltd"
initial_site.name = "foo"
initial_site.save()
Site.objects.create(domain="bar.domain.ltd", name="bar")
class Migration(migrations.Migration):
dependencies = [("sites", "0002_alter_domain_unique")]
operations = [migrations.RunPython(my_sites)]
此时./manage.py migrate
失败:
Applying sites.0001_initial... OK
Applying sites.0002_alter_domain_unique... OK
Applying dualsite.0001_set_sites...Traceback (most recent call last):
File "./manage.py", line 21, in <module>
main()
File "./manage.py", line 17, in main
execute_from_command_line(sys.argv)
File ".venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
utility.execute()
File ".venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File ".venv/lib/python3.7/site-packages/django/core/management/base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File ".venv/lib/python3.7/site-packages/django/core/management/base.py", line 364, in execute
output = self.handle(*args, **options)
File ".venv/lib/python3.7/site-packages/django/core/management/base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File ".venv/lib/python3.7/site-packages/django/core/management/commands/migrate.py", line 234, in handle
fake_initial=fake_initial,
File ".venv/lib/python3.7/site-packages/django/db/migrations/executor.py", line 117, in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
File ".venv/lib/python3.7/site-packages/django/db/migrations/executor.py", line 147, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File ".venv/lib/python3.7/site-packages/django/db/migrations/executor.py", line 245, in apply_migration
state = migration.apply(state, schema_editor)
File ".venv/lib/python3.7/site-packages/django/db/migrations/migration.py", line 124, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File ".venv/lib/python3.7/site-packages/django/db/migrations/operations/special.py", line 190, in database_forwards
self.code(from_state.apps, schema_editor)
File "dualsite/migrations/0001_set_sites.py", line 6, in my_sites
initial_site = Site.objects.get(id=1)
File ".venv/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File ".venv/lib/python3.7/site-packages/django/db/models/query.py", line 408, in get
self.model._meta.object_name
__fake__.DoesNotExist: Site matching query does not exist.
…<strong>但如果我拆分迁移它会起作用:./manage.py migrate sites; ./manage.py migrate
2) 现在我的数据库已经设置好了,是时候根据以下SITE_ID
设置来限制 URL core.settings.xxx
:
dualsite.utils
:
from django.contrib.sites.models import Site
from django.views.generic import TemplateView as tw
def check_site(view_asked):
view_returned = tw.as_view(template_name="403.dhtml")
if Site.objects.get_current().name == "foo":
view_returned = view_asked
return view_returned
core.urls
:
from django.urls import include, path
from django.views.generic import TemplateView as tw
from dualsite.utils import check_site
urlpatterns = [
# restricted : only foo.domain.ltd
path("", check_site(tw.as_view(template_name="base.dhtml")), name="home"),
path("hellofoo/", check_site(include("hellofoo.urls"))),
# full access : foo.domain.ltd & bar.domain.ltd
path("about/", tw.as_view(template_name="about.dhtml"), name="about"),
path("helloworld/", include("helloworld.urls")),
]
万岁:网址限制有效!!!
但 ./manage.py migrate sites
现在坏了:
Traceback (most recent call last):
File "./manage.py", line 21, in <module>
main()
File "./manage.py", line 17, in main
execute_from_command_line(sys.argv)
File ".venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
utility.execute()
File ".venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File ".venv/lib/python3.7/site-packages/django/core/management/base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File ".venv/lib/python3.7/site-packages/django/core/management/base.py", line 361, in execute
self.check()
File ".venv/lib/python3.7/site-packages/django/core/management/base.py", line 390, in check
include_deployment_checks=include_deployment_checks,
File ".venv/lib/python3.7/site-packages/django/core/management/commands/migrate.py", line 65, in _run_checks
issues.extend(super()._run_checks(**kwargs))
File ".venv/lib/python3.7/site-packages/django/core/management/base.py", line 377, in _run_checks
return checks.run_checks(**kwargs)
File ".venv/lib/python3.7/site-packages/django/core/checks/registry.py", line 72, in run_checks
new_errors = check(app_configs=app_configs)
File ".venv/lib/python3.7/site-packages/django/core/checks/urls.py", line 13, in check_url_config
return check_resolver(resolver)
File ".venv/lib/python3.7/site-packages/django/core/checks/urls.py", line 23, in check_resolver
return check_method()
File ".venv/lib/python3.7/site-packages/django/urls/resolvers.py", line 398, in check
for pattern in self.url_patterns:
File ".venv/lib/python3.7/site-packages/django/utils/functional.py", line 80, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File ".venv/lib/python3.7/site-packages/django/urls/resolvers.py", line 579, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File ".venv/lib/python3.7/site-packages/django/utils/functional.py", line 80, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File ".venv/lib/python3.7/site-packages/django/urls/resolvers.py", line 572, in urlconf_module
return import_module(self.urlconf_name)
File "/usr/lib/python3.7/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "core/urls.py", line 7, in <module>
path("", check_site(tw.as_view(template_name="base.dhtml")), name="home"),
File "dualsite/utils.py", line 9, in check_site
if Site.objects.get_current().name == "foo":
File ".venv/lib/python3.7/site-packages/django/contrib/sites/models.py", line 58, in get_current
return self._get_site_by_id(site_id)
File ".venv/lib/python3.7/site-packages/django/contrib/sites/models.py", line 30, in _get_site_by_id
site = self.get(pk=site_id)
File ".venv/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File ".venv/lib/python3.7/site-packages/django/db/models/query.py", line 402, in get
num = len(clone)
File ".venv/lib/python3.7/site-packages/django/db/models/query.py", line 256, in __len__
self._fetch_all()
File ".venv/lib/python3.7/site-packages/django/db/models/query.py", line 1242, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File ".venv/lib/python3.7/site-packages/django/db/models/query.py", line 55, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File ".venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1100, in execute_sql
cursor.execute(sql, params)
File ".venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 99, in execute
return super().execute(sql, params)
File ".venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 67, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File ".venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 76, in _execute_with_wrappers
return executor(sql, params, many, context)
File ".venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File ".venv/lib/python3.7/site-packages/django/db/utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File ".venv/lib/python3.7/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File ".venv/lib/python3.7/site-packages/django/db/backends/sqlite3/base.py", line 383, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: django_site
此时我决定在StackOverflow上寻求帮助……</p>
问题:Django 站点框架是否适合根据使用的域名限制 URL 访问?
奖金问题:
- 如果是:我在哪里弄错了迁移工具?
- 如果否:我可以使用哪个工具在 Django中保留访问规则(而不是将其放在 Nginx 中)
提前致谢 !