#python #django #one-to-one
#python #django #один к одному
Вопрос:
У меня есть модель 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)
Я получаю сообщение об ошибке:
Ошибка атрибута: объект ‘ReverseOneToOneDescriptor’ не имеет атрибута ‘header_text’
Любая помощь приветствуется.
Комментарии:
1. Попробуйте
Site.objects.get().settings.header_text
2.
Site
это неSite
объект, аSite
calss.3. Спасибо @dmitryguzeev, что сработало. Если вы создадите ответ, я пометю его как принятый
4.@Rutnet: это работает, если у вас есть один
Site
в базе данных. Если их несколько, это вызовет ошибку, так.get()
как невозможно узнать, какой сайт извлекать…5. @WillemVanOnsem Я согласен, но в моем случае использования я не могу использовать get_current_site, потому что я использую django-арендаторов. Кроме того, у меня не будет более одной записи для сайта
Ответ №1:
Site
является ссылкой на Site
класс, а не на Site
объект. Вы можете использовать get_current()
[Django-doc] для получения текущего сайта, а затем использовать отношение в обратном порядке:
from django.contrib.sites.shortcuts import get_current_site
get_current().settings.header_text
Если нет нескольких сайтов, нет особого смысла работать с ForeignKey
to 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
Комментарии:
1. Я должен добавить к этому, что «get_current ()» также работал, что, вероятно, является лучшим ответом. Разница между «get_current ()» и «get_current_site ()» заключается в том, что мне не нужно передавать запрос для первого.
2. @Rutnet: да, я допустил ошибку. Спасибо