-
Notifications
You must be signed in to change notification settings - Fork 10
Refactor: Class-based views - Eligibility index #2913
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7f333f2
c390004
9078671
35225b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,53 +7,67 @@ | |
from django.template.response import TemplateResponse | ||
from django.urls import reverse | ||
from django.utils.decorators import decorator_from_middleware | ||
from django.views.generic import FormView | ||
|
||
from benefits.routes import routes | ||
from benefits.core import recaptcha, session | ||
from benefits.core.middleware import AgencySessionRequired, RecaptchaEnabled, FlowSessionRequired | ||
from benefits.core.mixins import AgencySessionRequiredMixin, RecaptchaEnabledMixin | ||
from benefits.core.models import EnrollmentFlow | ||
from . import analytics, forms, verify | ||
|
||
TEMPLATE_CONFIRM = "eligibility/confirm.html" | ||
|
||
|
||
@decorator_from_middleware(AgencySessionRequired) | ||
@decorator_from_middleware(RecaptchaEnabled) | ||
def index(request): | ||
class IndexView(AgencySessionRequiredMixin, RecaptchaEnabledMixin, FormView): | ||
"""View handler for the enrollment flow selection form.""" | ||
agency = session.agency(request) | ||
session.update(request, eligible=False, origin=agency.index_url) | ||
|
||
# clear any prior OAuth token as the user is choosing their desired flow | ||
# this may or may not require OAuth, with a different set of scope/claims than what is already stored | ||
session.logout(request) | ||
|
||
context = {"form": forms.EnrollmentFlowSelectionForm(agency=agency)} | ||
|
||
if request.method == "POST": | ||
form = forms.EnrollmentFlowSelectionForm(data=request.POST, agency=agency) | ||
|
||
if form.is_valid(): | ||
flow_id = form.cleaned_data.get("flow") | ||
flow = EnrollmentFlow.objects.get(id=flow_id) | ||
session.update(request, flow=flow) | ||
|
||
analytics.selected_flow(request, flow) | ||
|
||
eligibility_start = reverse(routes.ELIGIBILITY_START) | ||
response = redirect(eligibility_start) | ||
else: | ||
# form was not valid, allow for correction/resubmission | ||
if recaptcha.has_error(form): | ||
messages.error(request, "Recaptcha failed. Please try again.") | ||
context["form"] = form | ||
context.update(agency.eligibility_index_context) | ||
response = TemplateResponse(request, "eligibility/index.html", context) | ||
else: | ||
context.update(agency.eligibility_index_context) | ||
response = TemplateResponse(request, "eligibility/index.html", context) | ||
|
||
return response | ||
template_name = "eligibility/index.html" | ||
form_class = forms.EnrollmentFlowSelectionForm | ||
|
||
def setup(self, request, *args, **kwargs): | ||
"""Initialize view attributes.""" | ||
super().setup(request, *args, **kwargs) | ||
self.agency = session.agency(request) | ||
|
||
def get_form_kwargs(self): | ||
"""Return the keyword arguments for instantiating the form.""" | ||
kwargs = super().get_form_kwargs() | ||
kwargs["agency"] = self.agency | ||
return kwargs | ||
|
||
def dispatch(self, request, *args, **kwargs): | ||
"""Initialize session state before handling the request.""" | ||
if not self.agency: | ||
return TemplateResponse(request, "200-user-error.html") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this CBV inherits from the Presumably if the request got this far, it has an agency in the session. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm this is a little more nuanced than I previously understood. We have This is sort of how it works. How MRO affects dispatch callsWhen we have a view like class
What this means for mixinsE.g. Scenario A: The view using the mixin does NOT define If Scenario B: The view using the mixin DOES define If If However, if TLDR;If possible, I think we should avoid implementing If not possible (e.g. we absolutely need to implement some logic in the CBVs |
||
|
||
session.update(request, eligible=False, origin=self.agency.index_url) | ||
# clear any prior OAuth token as the user is choosing their desired flow | ||
# this may or may not require OAuth, with a different set of scope/claims than what is already stored | ||
session.logout(request) | ||
return super().dispatch(request, *args, **kwargs) | ||
|
||
def form_valid(self, form): | ||
"""If the form is valid, set enrollment flow and redirect.""" | ||
flow_id = form.cleaned_data.get("flow") | ||
flow = EnrollmentFlow.objects.get(id=flow_id) | ||
session.update(self.request, flow=flow) | ||
|
||
analytics.selected_flow(self.request, flow) | ||
return redirect(reverse(routes.ELIGIBILITY_START)) | ||
|
||
def form_invalid(self, form): | ||
"""If the form is invalid, display error messages.""" | ||
if recaptcha.has_error(form): | ||
messages.error(self.request, "Recaptcha failed. Please try again.") | ||
return super().form_invalid(form) | ||
|
||
def get_context_data(self, **kwargs): | ||
"""Add agency-specific context data.""" | ||
context = super().get_context_data(**kwargs) | ||
if self.agency: | ||
context.update(self.agency.eligibility_index_context) | ||
return context | ||
|
||
|
||
@decorator_from_middleware(AgencySessionRequired) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this template name be defined on line 19, under
TEMPLATE_CONFIRM
, for consistency?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these global variables for template names were an artifact of having view functions. With class-based views, one of the main benefits is that everything is more cohesive and together, so I don't think we need to keep using these global variables for template names.