2

我希望能够做到:

def update_profile(request, username):
    user = Profile.objects.get(user__username=username)

    # update subset of profile, eg value_to_company is set in request.POST
    # but user (or an arbitrary number of other attributes) is not
    profile = ProfileForm(request.POST, instance=user)

    if not profile.is_valid():
        print profile.errors  #user is required

我遇到的问题是用户肯定存在并且是实例的一部分,我在文档中找不到任何内容表明实例数据不会进入绑定数据。但我也找不到任何明确表示它的东西。

(剩下的就是我为什么要以我的方式做事的理由,以及解决方案的想法,你可能不需要阅读它。)

如果你想知道我为什么要填写表格——对于这个问题来说不是必不可少的——那是因为我有这样的东西:

class Profile(models.Model):
    user = models.ForeignKey(auth.models.User)
    value_to_company = models.IntegerField()

class ValueField(forms.Field):
    def to_python(self, value):
        vals = {'high': 0,
                'mid': 1}
        return vals[value]

class ProfileForm(forms.ModelForm):
    value_to_company = ValueField()

    class Meta:
        model = Profile

也就是说,我已经在我的表单中执行 type api-to-internal-representation-coercion 并且我想继续使用它。

我可以重新实现 forms.is_valid() 循环,只需检查表单上已经存在的字段,比如:

# replaces `if not profile.is_valid()` above:
errors = []
for field in request.POST.iterkeys():
    if field in profile.fields:
        profile.fields[field].to_python()
        if not profile.fields['field'].clean():
            errors.append #something

(我实际上没有看过逻辑内部逻辑,所以我知道那是错误的,但你明白了。)

4

2 回答 2

0

您可能只需要添加exclude = ('user',)到您的表单中。表单实例主要确定初始值,如果您的表单包含用户字段,但该字段以空白值发布,它将尝试空白用户字段,从而导致错误。

于 2011-10-06T16:40:47.850 回答
0

我在django-piston找到了这个解决方案

它添加了merge_from_initial您在调用之前调用的其他表单方法,is_valid并从给定的对象中填充缺少的字段。

我对其进行了一些更改,并且正在使用:

class BaseModelForm(forms.ModelForm):
    """
    Subclass of `forms.ModelForm` which makes sure that the instance values are present in the form
    data, so you don't have to send all old values for the form to actually validate. Django does not
    do this on its own.
    """

    def merge_from_instance(self):
        # Internals
        self.data._mutable = True

        fun = lambda v: v not in self.data.keys()
        for field in filter(fun, self.fields.keys()):
            if field not in self.initial:
                continue
            value = self.initial.get(field)
            if isinstance(self.instance._meta.get_field(field), related.ManyToManyField):
                self.data.setlist(field, value)
            else:
                self.data[field] = value
于 2011-11-28T00:19:17.823 回答