Skip to content
This repository has been archived by the owner on Jan 28, 2020. It is now read-only.

Add a wizard to add a new candidacy for a person #968

Merged
merged 8 commits into from
Dec 1, 2016

Conversation

mhl
Copy link
Contributor

@mhl mhl commented Nov 30, 2016

The motivation of this pull request is to deal with the problem that the person edit page included post and party selects for every current election in the database - this might be repeated for hundreds of elections, which makes the page very slow to load and crashes some browsers. (See #740 for more details.)

On the DemocracyClub fork of YNR, this problem has been dealt with by using Javascript to dynamically add those form elements. However, in this upstream versions, so far, all of the site works without Javascript, on the principle that progressive enhancement is a Good Thing, so I was reluctant to merge those changes as-is. This pull request adds a method which is not Javascript-dependent to do the same thing, and we can use this as a base to apply the DC Javascript enhancement in the future. (Which I'm intending to do.)

The person edit page still uses lots of queries in its generation, which is bad, especially since there are fixes for those issues that I made in the DC fork; however, those fixes will apply most easily after the Javascript enhancement has been merged, so my plan is to get this merged, apply the Javascript enhancement of adding new candidacies, and then apply the fixes for excessive queries.

I guess @symroe or @struan might be best placed to review this, if either of you have time? n.b. @symroe, we discussed recently that the formtools wizard examples suggest you need to specify condition_dict as a keyword parameter to as_view, but it works fine when specified as a class attribute instead, as in this example.

add-candidacy-link
wizard-election-step

This doesn't look like a big deal, but the next commit will
introduce many more imports from forms.
Copy link
Member

@struan struan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks good. Some tiny comments for curiosity but they're not enough to hold up a merge.

)
with transaction.atomic():
person = get_object_or_404(Person, id=kwargs['person_id'])
LoggedAction.objects.create(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we not already have the Person from the context?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I'm a bit confused as why we are looking up the person here and not with the other things above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The context is only prepared for GET requests, and done is called when handling a POST request, but you're quite right that it's strange to have two bits of code that looks up the person... I've pushed a fixup that looks it up once by when overriding dispatch.

When you have many elections, the person edit page was taking a huge
amount of time to load because it included form fields for every
election regardless of whether the person was marked as standing in
that election or not.  In order to avoid that being required, this
commit introduces a wizard for adding a candidacy for a person.
This view doesn't require any Javascript, so should be a good basis
for progressive enhancement.
With hundreds of elections this resulted in a huge amount of HTML being
generated for the candidacy forms, which could crash the browser in
trying to render it, and made the generation of the page very slow.

This commit removes the code that adds editable candidacy fields for
every election to the person edit page. A subsequent commit will replace
that with a link to the new "add candidacy" wizard.
Previously, massive numbers of queries were needed to generate the
initial data for the person edit form when there were many elections
in the database.  This commit cuts that down substantially, although
there are still a large number of queries needed to generate the page
overall.
It is no longer the case that there will be candidacy fields for every
election, but having the standing field at its default of required=True
would have caused form validation errors if any were missed out. This
commit fixes that.
This makes the new "add candidacy" wizard accessible for adding
candidacies of other elections to the person edit page.
@mhl mhl force-pushed the progressive-add-candidacy-basic branch from 485f67c to d015057 Compare December 1, 2016 09:47
@mhl mhl merged commit d015057 into master Dec 1, 2016
Copy link
Collaborator

@symroe symroe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I didn't review this before it was merged! It looks excellent in general, and thank you for paying off my technical debt, Mark!

class AddCandidacyPickElectionForm(forms.Form):

election = forms.ModelChoiceField(
queryset=Election.objects.order_by('-election_date', 'name'))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should filter on current=True too.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or is the idea that people should be able to add non-current elections? I think this could be a bit confusing when there are 1000s of election objects in the database.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@symroe Yeah, my idea was that you need to have some way to add candidacies for historic elections in order to correct mistakes, or complete old data. But you're quite right that it'll be confusing in the more typical case. I've make a pull request that makes that restricts to current=True by default, but links to a version of the picker with all elections: #969

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants