Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从管理器返回自定义模型实例_Python_Django_Django Models_Django Queryset_Django Managers - Fatal编程技术网

Python 从管理器返回自定义模型实例

Python 从管理器返回自定义模型实例,python,django,django-models,django-queryset,django-managers,Python,Django,Django Models,Django Queryset,Django Managers,我有一个这样的模型,它将数据存储为键值对 class Setting(models.Model): company = models.ForeignKey( Company ) name = models.CharField( null=False, max_length=255 ) value= models.CharField( null=False, max_length=255 ) 我在这个

我有一个这样的模型,它将数据存储为键值对

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)
,我使用我的over-rided
get
方法执行一个
self.objects.filter(company=1)
,它返回一个对象列表。我可以生成一个自定义查询集,其中包含所有键值对作为字段

例如:

如果我的模型中的数据如下所示:

company  name    value
-------  ----    -----
1        theme   custom
1        mode    fast
1        color   green
我想返回一个查询集,当某人执行
Settings.objects.get(company=1)
时,该查询集会像这样旋转:

我尽量说得冗长,但如果我能更好地解释的话,一定要让我知道。我不确定Django模型是否允许这种情况

谢谢大家


编辑:使用代理模型

这是使用代理模型可以实现的吗?即,使用普通的
get
save
方法,使用一个基本模型来存储键值字段和自定义代理模型?

我是这样做的

我之所以需要这样做,是因为我有一个将信息存储为键值对的模型,我需要在该模型上构建一个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不会抛出错误)

该代理具有我希望在ModelFom中显示并在模型中存储为键值对的所有字段。现在,如果我需要添加更多字段,我可以简单地修改这个抽象模型,而不必编辑实际模型本身。现在我有了一个模型,我可以简单地在上面构建一个模型表单,如下所示:

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文档进行大量挖掘

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