fmt
fmt

Reputation: 993

Django partial update without form submission

I am using Django to write an app which is going to have an interface for automated requests and the like, which will not use a graphical/HTML UI. As of right now, I'm using a ModelForm to allow requests such as

POST /addFoo?a=1&b=Hello

which will create a new Foo with those fields and values and add it to the database. The view function looks like

def addFoo(request):
    form = FooForm(request)
    if form.is_valid():
        foo = form.save()
        return succeed(id=foo.id)
    else:
        return fail(code=0, error=form.errors)

where succeed and fail are functions to generate proper responses/log entries. This part works fine. However, I would like to write a similar function editFoo so that if there is an object with ID 1, then

POST /editFoo?id=1&a=42

will change that object's a field to 42. The view function as I currently have it is

def editFoo(request):
    try:
        foo = models.Foo.objects.get(id=request['id'])
    except:
        return fail(0, error=u'No such object exists!')
    form = FooForm(request, instance=foo)
    if form.is_valid():
        form.save()
        return succeed()
    else:
        return fail(code=1, error=form.errors)

However, when I test this form.errors contains error messages to the effect that the unspecified fields are required. Since the initiation of these requests will be by the client (that is, I cannot pre-load an HTML <form> for them to edit), I can't seem to find a way to make this sort of view work.

Thanks in advance for your advice.

EDIT: Model and Form are really simple:

class Foo(Model):
    a = IntegerField()
    b = CharField(max_length=23)

and

class FooForm(ModelForm):
    class Meta:
        model = Foo

Upvotes: 2

Views: 3637

Answers (1)

Peter DeGlopper
Peter DeGlopper

Reputation: 37319

You need to use a form class that contains only the fields that you're expecting to get from your POST, or that allows the fields to be omitted even though they are required on the model itself.

Limiting the fields present:

class FooEditForm(ModelForm):
    class Meta:
        model = Foo
        fields = ('a',)

Allowing the fields to be omitted:

class FooEditForm(ModelForm):
    class Meta:
        model = Foo

    a = forms.IntegerField(required=False)
    b = forms.CharField(required=False, max_length=23)

Or edit them in the form's __init__ method:

class FooEditForm(ModelForm):
    class Meta:
        model = Foo

    def __init__(self, *args, **kwargs):
        super(FooEditForm, self).__init__(*args, **kwargs)
        for field in self.fields.itervalues():
            field.required = False

Upvotes: 1

Related Questions