Question

Imagine this Model

class Session(models.Model):
    user = models.ForeignKey(User)
    start_time = models.DateTimeField()
    end_time = models.DateTimeField()

To add/update a session, I use this modelForm

class SessionForm(forms.ModelForm):
    class Meta:
        model = Session
        fields = ('start_time', 'end_time',)

As I need to prevent sessions of the same user to overlap, I made this form clean

def clean(self):
    cleaned_data = super(SessionForm, self).clean()
    start = cleaned_data.get('start_time')
    end = cleaned_data.get('end_time')
    conflicts = Session.objects.filter(
            start_time__lte=end,
            end_time__gte=start,
        )
    if any(conflicts):
        raise forms.ValidationError(_("%i conflicts found" % conflicts.count()))
    return cleaned_data

But as I'm adding the user after save()

if form.is_valid():
    session = form.save(False)
    session.user = request.user
    session.save()

How can I include it in the conflict check ?

In other words, how can I pass the user as a parameter to clean() ?

Was it helpful?

Solution

There's an alternative to overriding the __init__ method. Pass a session instance with the user set when you create the form.

session = Session(user=request.user)
form = SessionForm(data=request.POST, instance=session)
if form.is_valid():
    form.save()

Then in your clean method, you can access the user as self.instance.user.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top