2

I can't access request from the clean field of a ModelForm. I want to check that the request user is not trying to attend too many events.

I've tried this fix: Django: Accessing request in forms.py clean function

...among other things but am still struggling.

My form is this:

class EventEditForm(forms.ModelForm):

    class Meta:
        model = Event

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(EventEditForm, self).__init__(*args, **kwargs)


    name = forms.CharField(max_length=1024,
            initial="Give short, descriptive name",
            widget=forms.TextInput(attrs={'onfocus':'if(this.value=="Give short, descriptive name") this.value="";'}))
    location = forms.CharField(max_length=1024,
            initial="Be specific, give online map link",
            widget=forms.TextInput(attrs={'onfocus':'if(this.value=="Be specific, give online map link") this.value="";'}))
    dateTimeOptions = {
            'format': 'dd/mm/yyyy HH:ii P',
            'autoclose': 'true',
            'showMeridian': 'true',
            }
    date = forms.DateTimeField(label="Date and time",widget=DateTimeWidget(options=dateTimeOptions,
            attrs={'id':"date-time"}))
    host_act = forms.CharField(max_length=1024,
            initial="What act will you bring, if any?", required=False,
            widget=forms.TextInput(attrs={'onfocus':'if(this.value=="What act will you bring, if any?") this.value="";'}))
    description = forms.CharField(required=False, max_length=10240,
            initial="Give some details. Any activities prepared?",
            widget=forms.Textarea(attrs={'onfocus':'if(this.value=="Give some details. Any activities prepared?") this.value="";'}))


    def clean_location(self):
        cd = self.cleaned_data
        location = cd.get('location')
        if location == "Be specific, give online map link" or '':
            raise forms.ValidationError("Please enter a location")
        return location

    def clean_name(self):
        cd = self.cleaned_data
        name = cd.get('name')
        other_names = Event.objects.proposed(datetime.now)
        if name == "Give short, descriptive name" or '':
            raise forms.ValidationError("Please enter a name")
        return name

    def clean(self):
        """
        Check that there is not another event on at
        the same time and place. Then check that user has not committed
        to another event on the same date, even somewhere else.
        """
        cleaned_data = super(EventEditForm, self).clean()
        event_start_estimate = cleaned_data.get("date") - timedelta(hours=3)
        event_end_estimate = event_start_estimate + timedelta(hours=7)
        location = cleaned_data.get("location")
        events_on_date = Event.objects.\
            filter(date__range=[event_start_estimate,event_end_estimate])
        events_at_location_on_date = events_on_date.filter(location=location)
        print events_at_location_on_date
        # Check event clash is not this event clashing with itself
        try:
            events_with_same_date_and_location_id = events_at_location_on_date[0].id
        except:
            pass
        this_event_id = self.instance.id
        try:
            if events_with_same_date_and_location_id == this_event_id:
                events_at_location_on_date = False
        except:
            pass
        if events_at_location_on_date:
            raise forms.ValidationError("There is already an event on \
                this date. Please join this event or pick another \
                date and time. Note: You may have accidentally failed to \
                change the date with the picker.")
        print self.request
        user = self.request
        print user
        events_on_date_user_has_commit = events_on_date.filter(host__exact=user)
        if events_on_date_user_has_commit:
            raise forms.ValidationError("You are already committed to an event\
                on this date.")
        return cleaned_data

My view is:

class EventEditView(UpdateView):
    template_name = "edit_event.html"
    model=Event
    pk_url_kwarg='event_id'
    form_class = EventEditForm
Community
  • 1
  • 1
KindOfGuy
  • 3,081
  • 5
  • 31
  • 47

1 Answers1

3

You cannot access the request in a form. You need to pass it in from the view in some way. If you're using a FormView generic view, the answer you have linked to is a great way to do it. Looks like you are already expecting the request to be sent in:

self.request = kwargs.pop('request', None)

If you are using a function based view, or a non FormView classed based view, just pass in the request as a keyword argument when you initialize the form. For example:

form = EventEditForm(request.POST, request=request) # or self.request for a class based view
jproffitt
  • 6,225
  • 30
  • 42
  • Yes, I did use the fix in that answer, but I had implemented it slightly incorrectly. You spurred me to get it right. Thanks. – KindOfGuy Sep 25 '13 at 00:32