0

私はこのようなモデルを持ち、データをキーと値のペアとして格納しています。マネージャからカスタムモデルインスタンスを返す

class Setting(models.Model): 
    company = models.ForeignKey(
     Company 
    ) 
    name = models.CharField(
     null=False, max_length=255 
    ) 
    value= models.CharField(
     null=False, max_length=255 
    ) 

このモデルでは、getメソッドをオーバーライドするカスタムマネージャがあります。私のモデルSettings.objects.get(company=1)のようなクエリを実行すると、私は私の上書きされたgetメソッドを使ってオブジェクトのリストを返すself.objects.filter(company=1)を実行します。すべてのキーと値のペアをフィールドとして持つ単一のカスタムQuerySetを生成できますか?

例:

:私は誰かが Settings.objects.get(company=1)を実行したときに同じように旋回されるだろうクエリセットを返したいのですが

company name value 
------- ---- ----- 
1  theme custom 
1  mode fast 
1  color green 

私のモデルのデータがこのようなものだった場合

company theme mode  color 
------ ----- ----  ----- 
1  custom fast  green 

私は冗長にしようとしましたが、もっと説明しなければならないかどうか教えてください。私はDjango Modelsがこのシナリオを許しているかどうかはわかりません。

ありがとうございます。


編集:使用したプロキシモデル

これは、私は、すなわち、通常のgetsave方法とキー値フィールドとカスタムプロキシモデルを格納するためのベースモデルを持つプロキシモデルを使用して達成できるようなものですか?

答えて

0

ここで私はそれをしました。

キー値のペアとして情報を格納しているモデルがあり、そのモデルでModelFormを構築する必要がありましたが、ModelFormはキーと値のペアをフィールドとして表示する必要がありました。デフォルトでは、モデルのget()メソッドは常にモデルインスタンスを返します。カスタムモデルを使用する必要がありました。ここに私のキーと値のペアモデルがどのように見えるかです:

class Setting(models.Model): 
    domain = models.ForeignKey(Domain) 
    name = models.CharField(null=False, max_length=255) 
    value = models.CharField(null=False, max_length=255) 

    objects = SettingManager() 

私はget()メソッドをオーバーライドするために、この上のカスタムマネージャを構築しました:

class SettingManager(models.Manager): 

    def get(self, *args, **kwargs): 
     from modules.customer.proxies import * 
     from modules.customer.models import * 

     object = type('DomainSettings', (SettingProxy,), {'__module__' : 'modules.customer'})() 
     for pair in self.filter(*args, **kwargs): setattr(object, pair.name, pair.value) 

     setattr(object, 'domain', Domain.objects.get(id=int(kwargs['domain__exact']))) 
     return object 

このマネージャーは、この抽象モデルのインスタンスをインスタンス化します。このプロキシは、私は私のモデルでは、キーと値のペアとしての私のModelFomの表示や店舗をたいすべてのフィールドを持っている

class SettingProxy(models.Model): 

    domain = models.ForeignKey(Domain, null=False, verbose_name="Domain") 
    theme = models.CharField(null=False, default='mytheme', max_length=16) 
    message = models.CharField(null=False, default='Waddup', max_length=64) 

    class Meta: 
     abstract = True 

    def __init__(self, *args, **kwargs): 
     super(SettingProxy, self).__init__(*args, **kwargs) 
     for field in self._meta.fields: 
      if isinstance(field, models.AutoField): 
       del field 

    def save(self, *args, **kwargs): 
     with transaction.commit_on_success(): 
      Setting.objects.filter(domain=self.domain).delete() 

      for field in self._meta.fields: 
       if isinstance(field, models.ForeignKey) or isinstance(field, models.AutoField): 
        continue 
       else: 
        print field.name + ': ' + field.value_to_string(self) 
        Setting.objects.create(domain=self.domain, 
         name=field.name, value=field.value_to_string(self) 
        ) 

(Djangoはエラーをスローしませんので、抽象モデルは、テーブルを持っていません)。今ではフィールドを追加する必要がある場合は、この抽象モデルを変更して実際のモデル自体を編集する必要はありません。モデルを作成したので、モデルフォームを作成するだけです。

class SettingsForm(forms.ModelForm): 

    class Meta: 
     model = SettingProxy 
     exclude = ('domain',) 

    def save(self, domain, *args, **kwargs): 
     print self.cleaned_data 
     commit = kwargs.get('commit', True) 
     kwargs['commit'] = False 
     setting = super(SettingsForm, self).save(*args, **kwargs) 
     setting.domain = domain 
     if commit: 
      setting.save() 
     return setting 

私はこれが役立つことを望みます。これを理解するには、APIドキュメントを掘り下げる必要がありました。

関連する問題