У меня есть модель Django, которая создает отношение «один к одному» с сайтами Django.
from django.contrib.sites.models import Site
class SiteSettings(models.Model):
site = models.OneToOneField(Site, related_name = "settings", on_delete=models.CASCADE)
header_text = models.CharField(max_length=200, blank=True)
Я хочу получить доступ к полю header_text
в таблице SiteSettings из модели сайта. Я попытался получить значение, используя:
value = Site.settings.header_text
print(value)
Я получаю сообщение об ошибке:
AttributeError: объект ReverseOneToOneDescriptor не имеет атрибута 'header_text'
Любая помощь приветствуется.
Site
— это не Site
объект, а Site
класс.
Спасибо @dmitryguzeev, что сработало. Если вы создадите ответ, я отмечу его как принятый
@Rutnet: это работает, если у вас есть Site
в базе данных. Если их несколько, это вызовет ошибку, так как .get()
не может знать, какой сайт получить...
@WillemVanOnsem Я согласен, но в моем случае я не могу использовать get_current_site, потому что я использую django-tenants. Также у меня не будет более одной записи для сайта
@Rutnet: Если у вас нет нескольких Site
, вам не нужно ForeignKey
для Site
, в этом случае вы просто создаете модель с помощью header_text
, а затем получаете к ней доступ с помощью SiteSettings.objects.get().header_text
. Таким образом, это означает, что ваш SiteSettings
имеет ровно одну запись.
Да, я согласен с тем, что в обычных условиях это лучше всего, но я расширяю структуру и не хочу трогать основные модели.
Site
— это ссылка на класс Site
, а не на объект Site
. Вы можете использовать get_current() [Django-doc], чтобы получить текущий сайт, а затем использовать отношение в обратном порядке:
from django.contrib.sites.shortcuts import get_current_site
get_current().settings.header_text
Если нет нескольких сайтов, нет особого смысла работать с ForeignKey
до Site
в первую очередь, так как будет только один. В этом случае вы можете сделать модель:
# if there are no multiple Sites
from django.db import models
class SiteSettings(models.Model):
# no ForeignKey to Site
header_text = models.CharField(max_length=200, blank=True)
затем вы убедитесь, что для SiteSettings
есть ровно одна запись, и вы получаете к ней доступ с помощью:
# if there are no multiple Sites and only one SiteSettings record
SiteSettings.objects.get().header_text
вы можете немного повысить производительность, используя .only(…) [Django-doc]:
# if there are no multiple Sites and only one SiteSettings record
SiteSettings.objects.only('header_text').get().header_text
Я должен добавить к этому, что «get_current ()» также работал, что, вероятно, является лучшим ответом. Разница между "get_current()" и "get_current_site()" в том, что мне не нужно передавать запрос для первого.
@Rutnet: да, я ошибся. Спасибо
Попробуйте
Site.objects.get().settings.header_text