Доступ к однозначному значению поля таблицы в Django

#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: да, я допустил ошибку. Спасибо