2016-03-28 12 views
1

次のモデルがあります。Djangoカスタムマネージャのキーワード引数

class Site(models.Model): 
    domain = models.CharField(max_length=255, blank=True) 
    subdomain = models.CharField(max_length=255, blank=True) 

サイトにサブドメインがない場合は、デフォルトでwwwにします。これは簡単に行うことができます。しかし、Site.objects.get(domain='example.com')をサブドメインなしで呼び出すと、サブドメインをwwwに設定したいと考えています。私はこのような何かやってみました

class SitesManager(models.Manager): 
    def get_queryset(self, *args, **kwargs): 
     if 'domain' in kwargs.keys() and 'subdomain' not in kwargs.keys(): 
      kwargs['subdomain'] = 'www' 
     qs = super(SitesManager, self).get_queryset(args, kwargs) 
     return qs 

class Site(models.Model): 
    domain = models.CharField(max_length=255, blank=True) 
    subdomain = models.CharField(max_length=255, blank=True) 
    objects = SitesManager() 

どうやらget_querysetは、追加の引数を取りません。どのようなメソッドをオーバーライドする必要がありますか?

EDIT:

目標は、同じドメインやサブドメインを有する唯一つのサイトを持つことです。ただし、ドメインが同じでサブドメインが異なる複数のサイトがある場合もあれば、その逆の場合もあります。したがって、ドメインまたはサブドメインを一意にすることはできませんが、これはsaveメソッドで処理するのは簡単で、各ドメインのサブドメインの組み合わせが一意です。

我々は望ましい結果ではない2つの異なるサイトが得られているリンクhttp://example.comhttp://www.example.comを解析することによってサイトを追加しようとしたとき、私はだったに走った問題。だから私の解決策は、ちょうど空のサブドメインをwwwにデフォルト設定することでした。

問題は、後でhttp://example.comを解析してサイトが存在するかどうかを確認しようとすると、それが返されないことになります。 @mad_wombatは、ユーザーが求めていないものを返すべきではないと言いますが、サブドメインが決して空にならない場合は、それが実際にはwwwであるはずです。私は、代わりに電話を受けるか、カスタムメソッドを行う前に衛生検査を行うことができると思う。ちょうど私がget()呼び出しをこのインスタンスで想定されている方法で動作させるのではなく新しいものを追加しているようだ。

より一般的に言えば、データベースフィールドにデフォルト値がある場合、そのフィールドに空の値を固定することはできません。したがって、ユーザーが空の値を要求しないようにするのは理にかなっていません。そのフィールドに結果がないと伝えるよりも?

+0

ちなみに、getメソッドをオーバーライドすべきかどうかにかかわらず、誰かが私にその方法を教えてもらえますか?あなたが "コーディングするべきではない"たくさんのことがあります。それは、それを知る価値がないということを意味するものではありません。そして、私がこれを投稿した元の理由から、私はどこでもその答えを見つけることができなかったため、それを望むかもしれない人に答えを与える価値があるでしょう。 –

答えて

0

もちろん、get()とfilter()をオーバーライドすることができます。これにより、結果が多かれ少なかれ必要になります。しかし、あなたはおそらくそれをしたくありません。 QuerySetメソッドはRDBMSのPython APIで、filter()とget()はSQL文のPython表現です。そして、データベースと話すときに人々が一般的に期待することの1つは、彼らが求めているものを返すということです。ここで何をしようとしているのは、ユーザーが求めていないものを透過的に返すことです。あなたが唯一のユーザーであれば、誰もあなたのサブドメインが空であるかどうかをチェックすると、デフォルトで「www」を得ることからあなたを妨げるものはない

 
def get_site(domain, subdomain='www'): 
    return Site.objects.get(domain=domain, subdomain=subdomain) 

それとも、この代わりに、スタンドアローン機能の管理方法作ると同じようにそれを呼び出すことができますこの

 
Site.objects.get_site(domain, subdomain) 

他の人があなたのコードを使用している場合、get()またはfilter()が魔法の置換を行うことは期待できません。

+0

@mad_wombatはスポットになっています。get/filter呼び出しで「魔法」は起こりたくありません。彼の答えに追加するには、なぜこの仕事をしているのか自分に尋ねる必要があります。 'Site'オブジェクト_がサブドメインを必要とする場合は、この要件を満たすために 'save'メソッド(または 'clean'メソッドの1つ)をオーバーライドすることができます。 – Tristan

+0

@mad_wombat私は自分の質問を編集しました。私はあなたが一般的に言っている理由を理解していますが、ユーザーが求めていないものを返すべきではありません。しかし、空の値が変更されたデフォルト値を単に返すだけでは、空の値を求めるのではなく、誰かが空の値を求めた場合、なぜ失敗するのが良いのか分かりません。 –

+0

あなたが実際に探している答えについては、実際にはmanagerのget()を上書きすることができます。あなたの編集を見ると、save()の一意性を保証する必要はなく、必要なのはMetaの「unique_together」フィールドですhttps://docs.djangoproject.com/en/1.9/ref/models/options/# unique-together –

関連する問題