1

特定のサイトに関連付けられているオブジェクトの名前と表示を除いて、多くのURLで同じように動作するサイトを運営しています。このため、サイトモデルを拡張して、サイトに関する他のさまざまな情報を含め、標準のサイトオブジェクト情報をリクエストオブジェクトに入れるミドルウェアを作成しました。以前は、リクエストオブジェクトで必要な情報はサイト名だけでした。これは、Djangoが提供するサイトモデルから取得できました。拡張サイトモデル(以前は他のさまざまなアプリモデルでのみ使用されていた)に存在する情報が必要になりました。

request.site = Site.objects.get_current()これは、現在のサイトを取得しモデルから関連する拡張Siteオブジェクトを取得する必要があるため、各ページ()に1つのクエリを追加することから2つを追加することまでになります。

2つのクエリを使用せずにこの情報を取得する方法はありますか?それとも使用せずに?

models.py:

from django.contrib.sites.models import Site

class SiteMethods(Site):
    """
    Extended site model
    """
    colloquial_name = models.CharField(max_length=32,)
    ...

ミドルウェア.py:

class RequestContextMiddleware(object):
    """
    Puts the Site into each request object
    """
    def process_request(self, request):
        # This runs two queries on every page, instead of just one
        request.site = SiteMethods.objects.get(id=Site.objects.get_current().id)
        return None

私のsettings.pyファイルには、すべての共有構成データがあります。私のサーバーインスタンス(gunicorn)は[site]_settings.py、すべてのサイト固有の設定(Djangoを含むSITE_ID)を保持するロードするように構成されています。

try:
    from settings import *
except ImportError:
    pass

SITE_IDでハードコードされた参照を含まないオプション(存在する場合)を探しています[site]_settings.py

アップデート:

以下に示すように、サブクラス化されたオブジェクトは、引き続き親オブジェクトとすべての親オブジェクトの機能にアクセスできる必要があります。Siteオブジェクトの場合、奇妙なことに、これは当てはまらないようです。

>>> Site.objects.get_current()
<Site: website.com>
>>> SiteMethods.objects.get_current()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'Manager' object has no attribute 'get_current'
>>> SiteMethods.objects.select_related('site').get_current() # as suggested below
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'QuerySet' object has no attribute 'get_current'
>>> dir(SiteMethods)
['DoesNotExist', 'MultipleObjectsReturned', '__class__', '__delattr__', '__dict__',
'__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', 
'__metaclass__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', 
'__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', 
'__weakref__', '_base_manager', '_default_manager', '_deferred', '_get_FIELD_display', 
'_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', 
'_get_unique_checks', '_meta', '_perform_date_checks', '_perform_unique_checks', 
'_set_pk_val', 'clean', 'clean_fields', 'date_error_message', 'delete', 'full_clean', 
'objects', 'pk', 'prepare_database_save', 'save', 'save_base', 'serializable_value', 
'site_ptr', 'sitemethods', 'unique_error_message', 'validate_unique',]
4

1 に答える 1

2

サブクラス化したので、 をSite実行するだけでSiteMethods.objects.get_current()、 のインスタンスが得られSiteMethodsます。Django の MTI (Multiple Table Inheritance) の実装では親クラスに aを使用するため、 forOneToOneFieldも使用できるはずです。したがって、次のことを試してください。select_relatedsite

SiteMethods.objects.select_related('site').get_current()
于 2012-05-21T20:13:27.493 に答える