springload / madewithwagtail

A showcase of sites and apps made with Wagtail CMS, the easy to use, open source Django content management system
http://madewithwagtail.org
MIT License
84 stars 21 forks source link

Prevent developers to add themselves as `in_collaboration_with` #126

Open loicteixeira opened 6 years ago

loicteixeira commented 6 years ago

125 adds a new in_cooperation_with field to WagtailSitePages in order to share credit on a given site. However it is possible for a developer to add themselves.

It's a bit tricky as we need to either filter the choices of the Foreign Key and/or add some custom validation based on the parent page which isn't set until the page is saved 😞

loicteixeira commented 6 years ago

There is further complication in regard to limiting the choices as you can filter with static values, field values or a method which does not have access to the instance.

I tried to construct the parent's path from the fields values with limit_choices_to=(~Q(path__startswith=Substr('path', 1, Length('path') - Page.steplen))) but it raises FieldError: Expression contains mixed types. You must set output_field.

Weirdly enough, replacing Length('path') - Page.steplen by Length('path', output_field=CharField()) fixes the error but it's obviously dropping the - Page.steplen. Trying then to combine and cast the two with Cast(Length('path') - Page.steplen, CharField(max_length=5)) will now raise No function matches the given name and argument types. Further converting the second argument of Substr from 1 to '1' does not produce any error but does not produce the expected result either.

I'm not even sure why all this casting is necessary in the first place. Postgres documentation state that the length argument should be an integer, but using IntergerField still raise FieldError: Expression contains mixed types. You must set output_field as well.

There must be a better way 😞

loicteixeira commented 6 years ago

Actually, extending the base_form_class, we should be able to access self.parent_page. I'll play it with later.