Calling a custom model fields clean function

800 views
Skip to first unread message

Osiloke Emoekpere

unread,
Sep 30, 2012, 8:06:48 PM9/30/12
to django-res...@googlegroups.com
Hi There, 
I am trying to use a custom model field with DRF. The custom field is essentially of the form

class CustomTextField(models.TextField):
     def formfield(self):
         ....
    def clean(self, value, instance):
       return v.replace('help', "please") #lets say i do something like this

Running a trace on the PUT/POST view of DRF shows that the clean function is called and then the model instance is updated with the new value but when it finally saves the model, the "unclean" data is saved.

I'm a bit confused at this moment and would really appreciate if someone could explain this to me.
Thanks  


This is a great app and i'm really looking forward to v2.

Tom Christie

unread,
Oct 4, 2012, 5:24:27 PM10/4/12
to django-res...@googlegroups.com
Hi Osiloke,

  Sounds like a bug with custom model fields.  I would try to look into it, but I'm pushing as hard as I can to get 2.0 out the door right now (more info on that to follow shortly) so I'm afraid I'm going to have to be ruthless with prioritizing my time.

  I'm very optimistic the a whole bunch of ugly edge cases like this are going to disappear from 2.0 onwards, but until that happens I'm afraid there's not much I can offer in the way of help.

Cheers,

  Tom

Marko Tibold

unread,
Oct 4, 2012, 9:38:33 PM10/4/12
to django-res...@googlegroups.com
Hi Osiloke,

I managed to figure this one out.

The old DRF uses the cleaned_data from a custom OnTheFlyForm. Your CustomTextField's clean() method is called and the cleaned data is stored on a model instance (but not saved). But that instance is not used by DRF. DRF actually recreates  a new instance based on the cleaned data.

What you can do for now to circumvent this issue is creating an additional CustomTextField(forms.CharField) and create a ModelForm that uses this field.

Then on your Resource just set the form attribute to your new ModelForm.

Here's an implementation with the BlogPost example:


forms.py
######


from django import forms

from .models import BlogPost


class CustomTextField(forms.CharField):

    def clean(self, value):
        return value.replace('help', "please")  #lets say i do something like this


class BlogPostForm(forms.ModelForm):

    title = CustomTextField()

    class Meta:
        model = BlogPost



resources.py
##########

from blogpost.forms import BlogPostForm

class BlogPostResource(ModelResource):
    ….
    form = BlogPostForm
    ….


Good luck!

Osiloke Emoekpere

unread,
Oct 8, 2012, 11:40:52 AM10/8/12
to django-res...@googlegroups.com
I am actually using a custom form but not a custom form field. Your suggestion will work but i don't want to clean the data twice. What the custom model field's clean function actually does is remove unwanted html tags (scripts ... etc). 
So following marko's explanation and this topic on Custom validation. I created a clean function which just basically removes unwanted HTML from all character fields.

i.e

def clean(self):
        super(PagesForm, self).clean()
        cleaned_data = self.cleaned_data
        for f in self.fields:
            if self.fields[f].__class__ == forms.CharField:
                cleaned_data[f] = clean(cleaned_data[f]) 
        return cleaned_data

the function `clean` removes/suppresses unwanted html tags using the bleach module. I believe this is safer. Is this the best approach? I'm hoping V2 might have solved this. On that topic, is anyone (Marko) using DRF 2 in production. I was thinking of switching rather early.

Thanks for your help.

Tom Christie

unread,
Oct 8, 2012, 1:00:42 PM10/8/12
to django-res...@googlegroups.com
I don't believe anyone's using it in *production* yet although a few people have started working with it.
As I've said before, anyone willing to get started on using on REST framework 2 gets my absolute priority support,
and I think it's very very close to being release-ready now.

Osiloke Emoekpere

unread,
Oct 9, 2012, 6:32:06 AM10/9/12
to django-res...@googlegroups.com
ok, i guess i can start using it in production. At least i could help note or correct any bugs.

Thanks

Marko Tibold

unread,
Oct 16, 2012, 6:17:22 PM10/16/12
to django-res...@googlegroups.com
Hey, just returned from a week's holiday so sorry for the late reply. To answer your question, I haven't yet had the chance to use the version 2 branch in production. But would love to do so if the time comes available.

Marko
Reply all
Reply to author
Forward
0 new messages