Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: How do I add data to a ModelForm subclass before validation?

As part of a form validation in Django, I want to check when a user last made a post.

I've had a look at this, and this question on stackoverflow, which appear to address this issue, and initially used the accepted answer here. Essentially the process at the moment has been to add the request.user object during the

def form_valid(self, form):

method of the CreateView subclass. However, this doesn't allow the user variable to be used during form validation.

Since I want to access the user variable during validation, as the check on time since last post is logically validation, I need the user variable injected to the form earlier.

I've tried altering the get_initial() method:

def get_initial(self):
    initial = super(ArticleCreateView, self).get_initial()
    initial['user'] = self.request.user
    return initial

This successfully sets the ['user'] key in the initial dictionary, but this never makes it through the cleaning process, which deals only with the stuff in the ['data'] dictionary, and removes anything in initial. I've deliberately excluded user from the form display, but this appears to also remove it from the cleaning process and validation.

Is the correct way to do this to override the init() method of the Form, and the get_initial() method of the view, putting 'user' into initial, and then the form pulling the extra information from initial into the form at init()?

I'm looking to pass the request.user to the form, and then I can access it within the form-wide clean() method to do the additional checks, which amount to validation.

def clean(self):
    super(ArticleForm, self).clean()
    **check whether user has posted recently, if so, raise ValidationError**
    return self.cleaned_data

J

like image 887
jvc26 Avatar asked Jan 18 '23 07:01

jvc26


1 Answers

You can override get_form_kwargs method of the CreateView (ArticleCreateView in your case) to pass user to the form.

def get_form_kwargs(self):
    kwargs = super(ArticleCreateView, self).get_form_kwargs()
    kwargs['user'] = self.request.user
    return kwargs

Override your form's init method

...
def __init__(self, *args, **kwargs):
    self.user = kwargs.pop("user")

Now you can use self.user in the clean method.

like image 97
nmb.ten Avatar answered Feb 13 '23 02:02

nmb.ten