def merge_works(request, selected_queryset): if selected_queryset.model == WorkCluster: # Author is reviewing an existing WorkCluster from_cluster = True cluster = selected_queryset.first() works_to_merge_qs = cluster.works.order_by('id').prefetch_related( 'rating_set', 'genre') works_to_merge = list(works_to_merge_qs) else: # Author is merging those works from a Work queryset from_cluster = False works_to_merge_qs = selected_queryset.prefetch_related( 'rating_set', 'genre') works_to_merge = list(works_to_merge_qs) if request.POST.get('confirm'): # Merge has been confirmed if not from_cluster: cluster = WorkCluster(user=request.user, checker=request.user) cluster.save() # Otherwise we cannot add works cluster.works.add(*works_to_merge) # Happens when no ID was provided if not request.POST.get('id'): return None, None, MergeErrors.NO_ID final_id = int(request.POST.get('id')) final_work = Work.objects.get(id=final_id) missing_required_fields = overwrite_fields(final_work, request) # Happens when a required field was left empty if missing_required_fields: return None, missing_required_fields, MergeErrors.FIELDS_MISSING redirect_ratings(works_to_merge, final_work) redirect_staff(works_to_merge, final_work) redirect_related_objects(works_to_merge, final_work) WorkCluster.objects.filter(id=cluster.id).update( checker=request.user, resulting_work=final_work, merged_on=timezone.now(), status='accepted') return len(works_to_merge), final_work, None # Just show a warning if only one work was checked if len(works_to_merge) < 2: return None, None, MergeErrors.NOT_ENOUGH_WORKS fields_to_choose, fields_required, template_rows, rating_samples = create_merge_form( works_to_merge_qs) context = { 'fields_to_choose': ','.join(fields_to_choose), 'fields_required': ','.join(fields_required), 'template_rows': template_rows, 'rating_samples': rating_samples, 'queryset': selected_queryset, 'opts': Work._meta if not from_cluster else WorkCluster._meta, 'action': 'merge' if not from_cluster else 'trigger_merge', 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME } return len(works_to_merge), None, TemplateResponse( request, 'admin/merge_selected_confirmation.html', context)
def merge_works(request, selected_queryset, force=False): user = request.user if request else None if selected_queryset.model == WorkCluster: # Author is reviewing an existing WorkCluster from_cluster = True cluster = selected_queryset.first() works_to_merge_qs = cluster.works.order_by('id').prefetch_related('rating_set', 'genre') else: # Author is merging those works from a Work queryset from_cluster = False works_to_merge_qs = selected_queryset.order_by('id').prefetch_related('rating_set', 'genre') nb_works_to_merge = works_to_merge_qs.count() if request and request.POST.get('confirm'): # Merge has been confirmed rich_context = request.POST else: fields_to_choose, fields_required, template_rows, rating_samples, suggestions = create_merge_form(works_to_merge_qs) context = { 'fields_to_choose': ','.join(fields_to_choose), 'fields_required': ','.join(fields_required), 'template_rows': template_rows, 'rating_samples': rating_samples, 'queryset': selected_queryset, 'opts': Work._meta if not from_cluster else WorkCluster._meta, 'action': 'merge' if not from_cluster else 'trigger_merge', 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME } if all(field in suggestions for field in fields_required): rich_context = dict(context) for field in suggestions: rich_context[field] = suggestions[field] if force: rich_context['confirm'] = True if rich_context.get('confirm'): # Merge has been confirmed works_to_merge = list(works_to_merge_qs) if not from_cluster: cluster = WorkCluster(user=user, checker=user) cluster.save() # Otherwise we cannot add works cluster.works.add(*works_to_merge) # Happens when no ID was provided if not rich_context.get('id'): return None, None, MergeErrors.NO_ID final_id = int(rich_context.get('id')) final_work = Work.objects.get(id=final_id) # Notice how `cluster` always exist in this scope. # noinspection PyUnboundLocalVariable merge_handler = WorkClusterMergeHandler(cluster, works_to_merge, final_work) missing_required_fields = merge_handler.overwrite_fields( set(filter(None, rich_context.get('fields_to_choose').split(','))), set(filter(None, rich_context.get('fields_required').split(','))), rich_context) # Happens when a required field was left empty if missing_required_fields: return None, missing_required_fields, MergeErrors.FIELDS_MISSING merge_handler.perform_redirections() merge_handler.accept_cluster(user) return len(works_to_merge), merge_handler.target_work, None # Just show a warning if only one work was checked if nb_works_to_merge < 2: return None, None, MergeErrors.NOT_ENOUGH_WORKS return nb_works_to_merge, None, TemplateResponse(request, 'admin/merge_selected_confirmation.html', context)