开发者

How to validate a specific form's field with ignoring the required fields?

I want to validate just one field of a form. Here is my model:

class Person(models.Model): 
     user = models.ForeignKey(User)
     avatar = models.ImageField(upload_to=get_upload_path)
     creation_time = models.DateTimeField(auto_now=True)

In my view I want to allow users to update their avatar. So when the user clicks the Update button, I just want to send the avatar file and validate it only.

My update_avatar view is here:

@csrf_exempt
def update_avatar(request,user_id):
    profile_owner =开发者_开发知识库 Person.objects.get(user__id = user_id)
    form = ProfileSettings()
    if request.method == 'POST':
        form = ProfileSettings(request.POST,request.FILES)
        if form.is_valid():                                                                                                                                                                                                    
           return HttpResponse("ok")
    return HttpResponse("else")
#the code is not complete, this is for only testing purpose =) 

When i call form.is_valid() , I think it looks other information too which are required. So do you have an idea that how can i validate only avatar part ?


You could have two options, either you:

  1. write a custom form say AvatarForm and use it instead when updating the avatar, or you could
  2. write a custom function that validates the avatar field and call it instead of form.is_valid()

I say, go for the first, it is much easier that way and the validation is already handled for you when you call the is_valid() method. Here is how your form might look like:

class AvatarForm(forms.Form):
    avatar = forms.ImageField()


To expand on gladysbixly's answer, you could use ModelForms so you don't need to declare a field directly:

from django import forms


class AvatarForm(forms.ModelForm):
    class Meta:
        model = Person
        fields = (
            'avatar',
        )

I find this solution to a bit cleaner in most cases...


Check out django.forms.forms.BaseForm._clean_fields to see how Django validates each field when you call is_valid().

If you want to validate a single field in your form, bind the data as normal and then (basically) just call that field's clean() method.

Note that you will have to duplicate some of the setup code in _clean_fields():

@csrf_exempt
def update_avatar(request,user_id):
    profile_owner = Person.objects.get(user__id = user_id)

    if request.method == 'POST':
        form = ProfileSettings(request.POST, request.FILES)

        # Validate avatar.
        field   = form.fields['avatar']

        initial = form.initial.get('avatar', field.initial)
        upload  = field.widget.value_from_datadict(form.data, form.files, form.add_prefix('avatar'))

        try:
            avatar = field.clean(upload, initial)

            # Avatar is valid.
            return HttpResponse("ok")

        except ValidationError as e:
            # Avatar is invalid.
            return HttpResponse(e.message)
    else:
        form = ProfileSettings()

    return HttpResponse("else")

There are two gotchas that you have to watch out for, though:

  • If your form also has a clean_avatar() method defined, you'll need to explicitly call that.
  • You'll need to be careful about any relevant code that runs in the form's _post_clean() method as well.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜