Last active
September 6, 2018 11:51
-
-
Save RadicalPet/534b50bae5fe74d7b5c29de1f25bf22a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CreateProjectView(LoginRequiredMixin, SessionWizardView): | |
template_name = 'gigui/project.html' | |
form_list = [ | |
('1', KindSelectionForm), | |
('2', UrlGroupForm), | |
('3', CountriesForm), | |
('4', RulesKeywordsForm), | |
('5', OverviewForm), | |
] | |
def get(self, request, *args, **kwargs): | |
""" | |
This method handles GET requests. | |
If a GET request reaches this point, the wizard assumes that the user | |
just starts at the first step or wants to restart the process. | |
The data of the wizard will be resetted before rendering the first step | |
""" | |
self.storage.reset() | |
# reset the current step to the first step. | |
if 'cloned_pk' in self.kwargs: | |
self.storage.current_step = self.steps.last | |
else: | |
self.storage.current_step = self.steps.first | |
return self.render(self.get_form()) | |
def _get_cloned_instance_initial_kwarg(self, pk): | |
instance = Project.objects.filter(pk=pk, owner=self.request.user).first() | |
if not instance: | |
raise Http404('User {self.request.user} does not have any checks.') | |
kwargs = vars(instance) | |
kwargs['url_groups'] = list(instance.url_groups.all()) | |
kwargs['id'] = None | |
kwargs['name'] = f"Copy of {instance.name}" | |
return kwargs | |
def get_form_initial(self, step): | |
initial_dict = super().get_form_initial(step) | |
if 'cloned_pk' in self.kwargs: | |
initial_dict.update( | |
self._get_cloned_instance_initial_kwarg( | |
self.kwargs['cloned_pk'] | |
) | |
) | |
return initial_dict | |
def get_form_instance(self, step): | |
if 'pk' in self.kwargs: | |
return get_object_or_404( | |
Project, | |
pk=self.kwargs['pk'], | |
owner=self.request.user, | |
) | |
def done(self, form_list, **kwargs): | |
project_form = list(form_list)[4] | |
cleaned_data = self.get_all_cleaned_data() | |
instance = project_form.save(commit=False) | |
instance.schedule = 'onetime' | |
instance.owner = self.request.user | |
instance.kind = cleaned_data['kind'] | |
instance.countries = cleaned_data['countries'] | |
instance.rules = cleaned_data.get('rules', []) | |
instance.keywords = cleaned_data.get('keywords', []) | |
instance.urls = list(itertools.chain( | |
*cleaned_data["url_groups"].values_list('urls', flat=True) | |
)) | |
if "related_urls" in cleaned_data: | |
instance.related_urls = cleaned_data["related_urls"] | |
instance.priority_words = cleaned_data["priority_words"] | |
instance.save() | |
messages.add_message(self.request, messages.INFO, f'Your project "{instance.name}" was saved.') | |
instance.url_groups.set(cleaned_data["url_groups"]) | |
return redirect('gigui:manage_checks') | |
def render_goto_step(self, step): | |
""" | |
If navigating to a step and prior step isn't filled, | |
render form errors | |
""" | |
# TODO: write tests! | |
if step > self.steps.current: | |
# the step before clicked tab must be filled | |
required_step = str(int(step) - 1) | |
can_continue = required_step in self.get_filled_steps() | |
if not can_continue: | |
return super().render_goto_step(self.steps.current) | |
return super().render_goto_step(step) | |
def get_filled_steps(self): | |
# TODO: write docstring and tests! | |
try: | |
return [ | |
step | |
for step in ['1', '2', '3', '4', '5'] | |
if self.get_cleaned_data_for_step(step) is not None | |
] | |
except UnknownKindError: | |
logger.warning('Cannot process steps without settings kind in step 1!') | |
return [] | |
def get_context_data(self, form: ModelForm, **kwargs): | |
context = super().get_context_data(form=form, **kwargs) | |
context['filled_steps'] = self.get_filled_steps() | |
context['current_step'] = self.steps.current | |
if int(self.steps.current) >= 2: | |
if 'cloned_pk' in self.kwargs: | |
cleaned_data = self.get_form_initial('1') | |
cleaned_data = self.get_cleaned_data_for_step('1') | |
check_title = dict(PROJECT_TYPE_CHOICES)[cleaned_data['kind']]['title'] | |
context['project_kind'] = cleaned_data['kind'] | |
context['breadcrumbs'] = check_title | |
context['step4_name'] = ('Keywords' if cleaned_data['kind'] == 'popunder' else 'Rules') | |
if int(self.steps.current) == 2: | |
context['modal_form'] = UrlGroupModalForm | |
if int(self.steps.current) == 4: | |
if 'rules' in form.fields and not form.is_valid() and 'rules' in form.errors: | |
errors = [] | |
for error in form.errors['rules']: | |
position, message = error.split(': ', 1) | |
position = re.findall('\d+', position) | |
errors.append((position, message)) | |
context['rules_errors'] = json.dumps(errors) | |
if int(self.steps.current) == 5: | |
if 'cloned_pk' in self.kwargs: | |
context['url_groups'] = self.get_form_initial('2')['url_groups'] | |
else: | |
context['url_groups'] = self.get_cleaned_data_for_step('2')['url_groups'] | |
if 'cloned_pk' in self.kwargs: | |
selected_countries = self.get_form_initial('3')['countries'] | |
else: | |
selected_countries = self.get_cleaned_data_for_step('3')['countries'] | |
context['countries'] = [ | |
(code, name) | |
for code, name in django_countries.countries | |
if code in selected_countries | |
] | |
if 'cloned_pk' in self.kwargs: | |
rules = self.get_form_initial('4').get('rules', {}) | |
else: | |
rules = self.get_cleaned_data_for_step('4').get('rules', {}) | |
context['rules'] = ( | |
render_rules(rules) | |
if rules | |
else {} | |
) | |
if 'cloned_pk' in self.kwargs: | |
context['keywords'] = self.get_form_initial('4').get('keywords', []) | |
else: | |
context['keywords'] = self.get_cleaned_data_for_step('4').get('keywords', []) | |
return context | |
def get_form_kwargs(self, step=None): | |
kwargs = super().get_form_kwargs(step=step) | |
prev_step = self.get_prev_step(step) | |
kwargs['previous_step'] = prev_step | |
if step == "2": | |
step1_data = self.get_cleaned_data_for_step('1') | |
if step1_data: | |
kwargs["kind"] = self.get_cleaned_data_for_step('1')["kind"] | |
kwargs['owner'] = self.request.user | |
elif step == "4": | |
step1_data = self.get_cleaned_data_for_step('1') | |
if step1_data: | |
kwargs["kind"] = step1_data["kind"] | |
elif step == "5": | |
# pass own projects to check if project name is duplicated | |
qs = Project.objects.filter(owner=self.request.user) | |
if "pk" in self.kwargs: | |
qs = qs.exclude(pk=self.kwargs.get("pk", None)) | |
kwargs["qs"] = qs | |
return kwargs |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment