【问题标题】:django.db.utils.ProgrammingError: relation "django_site" does not existdjango.db.utils.ProgrammingError:关系“django_site”不存在
【发布时间】:2020-07-27 09:06:44
【问题描述】:

Django 3.0.8

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

settings.py

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

SITE_ID = 1 # For the sites framework.

urls.py

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

feeds.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()

utils.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的导入和使用,那么迁移就执行好了。

您能告诉我如何处理这个问题吗?

【问题讨论】:

  • Feed 类是否继承自模型?
  • 没有。我编辑了问题以显示它是如何组织的。它是一个 django 提要框架。像这样加载: from django.contrib.syndication.views import Feed
  • 你能不能试着把这行链接 = get_site_address() 变成一个 lambda 沿着这个链接 = lambda: _: get_site_address()
  • 我是这样做的:link = lambda _: get_site_address() 它没有帮助。
  • 您遇到的问题很可能是由于您在开始时加载的 url 涉及查询,而此时的模型尚未正确加载。您的代码也会在空 db 上失败。您可以尝试将这些内容隐藏在方法中,或者将其设置为 Feed 上的属性以延迟执行。

标签: django django-sites


【解决方案1】:

所以,最终更新:

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

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

除了将导入隐藏在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()),
]

【讨论】:

  • 我编辑了我的问题。它是一个新创建的数据库。到目前为止还没有迁移。
  • 我试过了。它没有帮助。像这样没有帮助:model_class= apps.get_model("sites.Site", require_ready=False) site = model_class.objects.first().name
  • 问题本地化不在 get_site 中。它在 urls.py 中。当我在那里发表评论时,一切正常。像这样: # from feeds.feeds import RssFeed urlpatterns += [ # path('rss/', RssFeed(), name="rss"),
  • 呃,您是在 RssFeed 的类定义中的声明时调用该函数。你真的应该避免这种情况。
  • 我无法理解你的想法。我已经这样重写了: link = get_site_address() class RssFeed(Feed): link = link 那就是我刚刚在类外调用了函数。它没有帮助。然后我在课堂上这样写:link =“localhost:8000”也没有帮助。
猜你喜欢
  • 2021-02-13
  • 1970-01-01
  • 2014-07-18
  • 2021-03-30
  • 1970-01-01
  • 2018-05-11
  • 2014-10-25
  • 2019-03-15
  • 2018-03-23
相关资源
最近更新 更多