首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从管理器返回自定义模型实例

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

Stack Overflow用户
提问于 2011-09-09 13:25:37
回答 1查看 481关注 0票数 0

我有一个类似于此的模型,并将数据存储为键值对。

代码语言:javascript
复制
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,它将所有的键值对作为字段。

示例:

如果我的模型中的数据是这样的:

代码语言:javascript
复制
company  name    value
-------  ----    -----
1        theme   custom
1        mode    fast
1        color   green

我想返回一个查询集,当有人执行Settings.objects.get(company=1)时,这个查询集会像这样旋转

代码语言:javascript
复制
company  theme    mode     color
------   -----    ----     -----
1        custom   fast     green

我试着长篇大论,但请告诉我是否需要更好地解释。我不确定Django模型是否允许这种情况。

谢谢大家。

编辑:使用代理模型

这是我可以使用代理模型完成的事情吗?比如有一个基模型来存储键值字段,以及使用普通的getsave方法来定制代理模型?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-09-14 11:08:02

我就是这么做的。

我需要这样做,因为我有一个将信息存储为键值对的模型,我需要在该模型上构建一个ModelForm,但是ModelForm应该将键值对显示为字段,即将行枢轴到列。默认情况下,模型的get()方法总是返回自身的模型实例,我需要使用自定义模型。下面是我的键值对模型的样子:

代码语言:javascript
复制
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()方法:

代码语言:javascript
复制
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

此Manager将实例化此抽象模型的实例。(抽象模型没有表,这样Django就不会抛出错误)

代码语言:javascript
复制
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了,如下所示:

代码语言:javascript
复制
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文档中进行大量的挖掘。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7362315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档