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嗎?

例子:

如果在我的模型中的數據是這樣的:

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

我想返回查詢組會擺動,像這樣,當有人執行Settings.objects.get(company=1)

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

我試過了,但是如果我應該更好地解釋,請告訴我。我不確定Django模型是否允許這種情況。

謝謝大家。


編輯:使用代理模式

這是不是我可以完成使用具有示範基地,以存儲與正常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 

該經理將實例化這個抽象模型的實例。 (抽象模型沒有表,以便Django不扔了錯誤)

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) 
        ) 

該代理具有的一切,我想在我的ModelFom顯示並存儲爲在我的模型鍵值對的領域。現在,如果我需要添加更多的字段,我可以簡單地修改這個抽象模型,而不必編輯實際模型本身。現在,我有一個模型,我可以簡單地在其上構建的ModelForm像這樣:

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文檔進行大量挖掘才能弄清楚。