将表单字段存储为键值/单独的行

发布于 2024-12-03 10:44:31 字数 586 浏览 0 评论 0原文

我在 Django 中有一个简单的表单,如下所示:

class SettingForm(forms.Form):
    theme = forms.CharField(rrequired=True,
        initial='multgi'
    )
    defaultinputmessage = forms.CharField(required=True,
        initial='Type here to begin..'
    )

...存储它的模型如下所示:

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

提交表单时,如何将表单字段存储为键值对,然后呈现页面时,如何我可以用键的值初始化表单吗?我曾尝试寻找此方法的实现,但一直找不到。

有什么帮助吗?

谢谢。

I have a simple form in Django that looks like this:

class SettingForm(forms.Form):
    theme = forms.CharField(rrequired=True,
        initial='multgi'
    )
    defaultinputmessage = forms.CharField(required=True,
        initial='Type here to begin..'
    )

...and the model to store it looks like:

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

When the form is submitted, how can i store the form fields as key value pairs and then when the page is rendered, how can I initialize the form with the key's value. I've tried looking for an implementation of this but have been unable to find one.

Any help?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只等公子 2024-12-10 10:44:31

我假设您想将“主题”存储为名称,将值存储为值,与默认输入消息相同。如果是这种情况,这应该有效:

form = SettingForm({'theme': 'sometheme', 'defaultinputmessage': 'hello'})
if form.is_valid():
    for key in form.fields.keys():
        setting = Setting.objects.create(name=key, value=form.cleaned_data[key])

I'm assuming you want to store 'theme' as the name and the value as the value, same for defaultinputmessage. If that's the case, this should work:

form = SettingForm({'theme': 'sometheme', 'defaultinputmessage': 'hello'})
if form.is_valid():
    for key in form.fields.keys():
        setting = Setting.objects.create(name=key, value=form.cleaned_data[key])
蹲在坟头点根烟 2024-12-10 10:44:31

我是这样做的。

我需要这样做,因为我有一个将信息存储为键值对的模型,并且我需要在该模型上构建一个 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 文档才能弄清楚这一点。

Here's how I did it.

I needed to do this because I had a Model that stored information as key value pairs and I needed to build a ModelForm on that Model but the ModelForm should display the key-value pairs as fields i.e. pivot the rows to columns. By default, the get() method of the Model always returns a Model instance of itself and I needed to use a custom Model. Here's what my key-value pair model looked like:

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

I built a custom manager on this to override the get() method:

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

This Manager would instantiate an instance of this abstract model. (Abstract models don't have tables so Django doesn't throw up errors)

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

This proxy has all the fields that I'd like display in my ModelFom and store as key-value pairs in my model. Now if I ever needed to add more fields, I could simply modify this abstract model and not have to edit the actual model itself. Now that I have a model, I can simply build a ModelForm on it like so:

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

I hope this helps. It required a lot of digging through the API docs to figure this out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文