首页 > 解决方案 > django.db.utils.ProgrammingError:关系“django_site”不存在

问题描述

Django 3.0.8

数据库是新创建的。到目前为止没有迁移。

设置.py

INSTALLED_APPS = [
    'django.contrib.sites',  # DJANGO_APP. Necessary for the built in sitemap framework.
...
]

SITE_ID = 1 # For the sites framework.

网址.py

from feeds.feeds import RssFeed
urlpatterns += [
    path('rss/', RssFeed(), name="rss"),
...

提要.py

from django.contrib.syndication.views import Feed
from general.utils import get_site_address

class RssFeed(Feed):
    title = "Pcask.ru: все о компьютерах, гаджетах и программировании."
    link = get_site_address()

实用程序.py

from django.contrib.sites.models import Site

def get_site():
    site = Site.objects.first().name
    return site


def get_protocol():
    if HTTPS:
        protocol = "https://"
    else:
        protocol = "http://"

    return protocol


def get_site_address():
    return "".format(get_protocol(), get_site())

问题

首先,我必须在使用站点框架(https://docs.djangoproject.com/en/3.0/ref/contrib/sites/#enabling-the-sites-framework)时进行迁移。

$ python manage.py migrate
Traceback (most recent call last):
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
psycopg2.errors.UndefinedTable: relation "django_site" does not exist
LINE 1: ..."django_site"."domain", "django_site"."name" FROM "django_si...
                                                             ^


The above exception was the direct cause of the following exception:

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 "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 395, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/core/management/base.py", line 328, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/core/management/base.py", line 366, in execute
    self.check()
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/core/management/base.py", line 392, in check
    all_issues = self._run_checks(
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/core/management/commands/migrate.py", line 64, in _run_checks
    issues.extend(super()._run_checks(**kwargs))
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/core/management/base.py", line 382, in _run_checks
    return checks.run_checks(**kwargs)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/core/checks/registry.py", line 72, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/core/checks/urls.py", line 13, in check_url_config
    return check_resolver(resolver)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/core/checks/urls.py", line 23, in check_resolver
    return check_method()
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/urls/resolvers.py", line 407, in check
    for pattern in self.url_patterns:
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/urls/resolvers.py", line 588, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/urls/resolvers.py", line 581, in urlconf_module
    return import_module(self.urlconf_name)
  File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/michael/PycharmProjects/pcask/pcask/pcask/urls.py", line 31, in <module>
    from feeds.feeds import RssFeed
  File "/home/michael/PycharmProjects/pcask/pcask/feeds/feeds.py", line 14, in <module>
    class RssFeed(Feed):
  File "/home/michael/PycharmProjects/pcask/pcask/feeds/feeds.py", line 16, in RssFeed
    link = get_site_address()
  File "/home/michael/PycharmProjects/pcask/pcask/general/utils.py", line 123, in get_site_address
    return "".format(get_protocol(), get_site())
  File "/home/michael/PycharmProjects/pcask/pcask/general/utils.py", line 109, in get_site
    site = Site.objects.first().name
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/db/models/query.py", line 664, in first
    for obj in (self if self.ordered else self.order_by('pk'))[:1]:
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/db/models/query.py", line 276, in __iter__
    self._fetch_all()
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/db/models/query.py", line 1261, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/db/models/query.py", line 57, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/cachalot/monkey_patch.py", line 36, in inner
    return original(compiler, *args, **kwargs)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/cachalot/monkey_patch.py", line 87, in inner
    return _get_result_or_execute_query(
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/cachalot/monkey_patch.py", line 59, in _get_result_or_execute_query
    result = execute_query_func()
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/cachalot/monkey_patch.py", line 75, in <lambda>
    execute_query_func = lambda: original(compiler, *args, **kwargs)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1152, in execute_sql
    cursor.execute(sql, params)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 100, in execute
    return super().execute(sql, params)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/cachalot/monkey_patch.py", line 128, in inner
    return original(cursor, sql, *args, **kwargs)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/michael/PycharmProjects/pcask/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "django_site" does not exist
LINE 1: ..."django_site"."domain", "django_site"."name" FROM "django_si...

如果我评论那个 urlpattern,Site 的导入和使用,那么迁移就执行好了。

你能给我一个提示如何处理这个问题吗?

标签: djangodjango-sites

解决方案


所以,最终更新:

您正在做的是调用类定义中的函数:

class RssFeed(Feed):
    title = "Pcask.ru: все о компьютерах, гаджетах и программировании."
    link = get_site_address()  # <---- problem

事情是Feed.get_feed站点框架已经有了逻辑。我同意,重写逻辑有点麻烦,但还要看看:

    def _get_dynamic_attr(self, attname, obj, default=None):
        try:
            attr = getattr(self, attname)
        except AttributeError:
            return default
        if callable(attr):
            # Check co_argcount rather than try/excepting the function and
            # catching the TypeError, because something inside the function
            # may raise the TypeError. This technique is more accurate.
            try:
                code = attr.__code__
            except AttributeError:
                code = attr.__call__.__code__
            if code.co_argcount == 2:       # one argument is 'self'
                return attr(obj)
            else:
                return attr()
        return attr

这意味着您将链接实现为:

class RssFeed(Feed):
    title = "Pcask.ru: все о компьютерах, гаджетах и программировании."
    link = get_site_address  # No brackets

除了隐藏 import 里面get_site_address

但是,您应该更仔细地查看 Feed.get_feed(),因为您获得了一个对象,并且预计会返回一个完整的链接,而不仅仅是一个站点地址。

作为参考,此代码有效,并放在根 url conf 中:

from django.contrib.syndication.views import Feed

HTTPS = False


def get_link(obj):
    from django.contrib.sites.models import Site

    main_site = Site.objects.order_by("id").first()
    assert main_site is not None, "Sites have been deleted!"

    try:
        path = getattr(obj, "get_absolute_url")()
    except AttributeError as e:
        raise AttributeError("Do not know how to generate url path") from e

    return f"{get_protocol()}://{main_site.domain}{path}"


def get_protocol():
    return "https" if HTTPS else "http"


class RssFeed(Feed):
    title = "Pcask.ru: все о компьютерах, гаджетах и программировании."
    link = get_link

# urls.py
urlpatterns = [
    path("rss/", RssFeed()),
]

推荐阅读