def perform_update(self, serializer): """ Validates report for mandatory fields Changes status of the report Creates a Barrier Instance out of the report Sets up default status Adds next_steps_summary, if exists, as a new note """ # validate and submit a report report = self.get_object() user = self.request.user barrier_obj = report.submit_report(user) # add next steps, if exists, as a new COMMENT note if barrier_obj.next_steps_summary: kind = self.request.data.get("kind", BARRIER_INTERACTION_TYPE["COMMENT"]) Interaction( barrier=barrier_obj, text=barrier_obj.next_steps_summary, kind=kind, created_by=user, ).save() Profile.objects.get_or_create(user=user) if user.profile.sso_user_id is None: update_user_profile(user, self.request.auth.token) # Create default team members new_members = ( TeamMember(barrier=barrier_obj, user=user, role=TeamMember.REPORTER, default=True), TeamMember(barrier=barrier_obj, user=user, role=TeamMember.OWNER, default=True), ) # using a helper here due to - https://django-simple-history.readthedocs.io/en/2.8.0/common_issues.html bulk_create_with_history(new_members, TeamMember)
def test_bulk_create_history_with_duplicates_ignore_conflicts(self): bulk_create_with_history(self.data_with_duplicates, PollWithUniqueQuestion, ignore_conflicts=True) self.assertEqual(PollWithUniqueQuestion.objects.count(), 2) self.assertEqual(PollWithUniqueQuestion.history.count(), 2)
def test_bulk_create_history_with_default_date(self): date = datetime(2020, 7, 1) bulk_create_with_history(self.data, Poll, default_date=date) self.assertTrue( all([history.history_date == date for history in Poll.history.all()]) )
def form_valid(self, form): context_data = self.get_context_data() periods = context_data["periods"] if periods.is_valid(): fy = form.save() self.object = fy periods.instance = fy periods.save(commit=False) period_instances = [p.instance for p in periods] period_instances.sort(key=lambda p: p.month_start) i = 1 for period in period_instances: period.fy_and_period = f"{fy.financial_year}{str(i).rjust(2, '0')}" period.period = str(i).rjust(2, '0') i = i + 1 bulk_create_with_history([*period_instances], Period) first_period_of_fy = fy.first_period() mod_settings = ModuleSettings.objects.first() # when a FY is created for the first time we need to set the default # posting periods for each posting module in the software for setting, period in mod_settings.module_periods().items(): if not period: setattr(mod_settings, setting, first_period_of_fy) mod_settings.save() return HttpResponseRedirect(self.get_success_url()) return self.render_to_response(context_data)
def test_bulk_create_history_with_default_user(self): user = User.objects.create_user("tester", "*****@*****.**") bulk_create_with_history(self.data, Poll, default_user=user) self.assertTrue( all([history.history_user == user for history in Poll.history.all()]) )
def post(self, request, *args, **kwargs): poll_info_list = [ {"question": "1", "pub_date": date(2020, 1, 1)}, {"question": "2", "pub_date": date(2020, 1, 2)}, ] polls_to_create = [Poll(**poll_info) for poll_info in poll_info_list] bulk_create_with_history(polls_to_create, Poll) return HttpResponse(status=200)
def test_bulk_create_history_on_model_without_history_raises_error(self): self.data = [ Place(id=1, name="Place 1"), Place(id=2, name="Place 2"), Place(id=3, name="Place 3"), ] with self.assertRaises(NotHistoricalModelError): bulk_create_with_history(self.data, Place)
def test_bulk_create_history_on_objects_that_already_exist(self): Poll.objects.bulk_create(self.data) with self.assertRaises(IntegrityError): bulk_create_with_history(self.data, Poll) self.assertEqual(Poll.objects.count(), 5) self.assertEqual(Poll.history.count(), 0)
def test_bulk_create_works_with_excluded_fields(self): bulk_create_with_history(self.data, PollWithExcludeFields) self.assertEqual(Poll.objects.count(), 0) self.assertEqual(Poll.history.count(), 0) self.assertEqual(PollWithExcludeFields.objects.count(), 5) self.assertEqual(PollWithExcludeFields.history.count(), 5)
def test_bulk_create_history_alternative_manager(self): bulk_create_with_history( self.data, PollWithAlternativeManager, ) self.assertEqual(PollWithAlternativeManager.all_objects.count(), 5) self.assertEqual(PollWithAlternativeManager.history.count(), 5)
def test_bulk_create_history_on_model_without_history_raises_error(self): self.data = [ Place(id=1, name="Place 1"), Place(id=2, name="Place 2"), Place(id=3, name="Place 3"), ] with self.assertRaises(NotHistoricalModelError): bulk_create_with_history(self.data, Place)
def test_bulk_create_history_on_objects_that_already_exist(self): Poll.objects.bulk_create(self.data) with self.assertRaises(IntegrityError): bulk_create_with_history(self.data, Poll) self.assertEqual(Poll.objects.count(), 5) self.assertEqual(Poll.history.count(), 0)
def test_bulk_create_works_with_excluded_fields(self): bulk_create_with_history(self.data_with_excluded_fields, PollWithExcludeFields) self.assertEqual(Poll.objects.count(), 0) self.assertEqual(Poll.history.count(), 0) self.assertEqual(PollWithExcludeFields.objects.count(), 5) self.assertEqual(PollWithExcludeFields.history.count(), 5)
def test_bulk_create_history_with_default_change_reason(self): bulk_create_with_history(self.data, Poll, default_change_reason="my change reason") self.assertTrue( all([ history.history_change_reason == "my change reason" for history in Poll.history.all() ]))
def test_bulk_create_history_with_relation_name(self): self.data = [ Street(name="Street 1"), Street(name="Street 2"), Street(name="Street 3"), Street(name="Street 4"), ] bulk_create_with_history(self.data, Street) self.assertEqual(Street.objects.count(), 4) self.assertEqual(Street.log.count(), 4)
def test_bulk_create_history_with_duplicates(self): with transaction.atomic(), self.assertRaises(IntegrityError): bulk_create_with_history( self.data_with_duplicates, PollWithUniqueQuestion, ignore_conflicts=False, ) self.assertEqual(PollWithUniqueQuestion.objects.count(), 0) self.assertEqual(PollWithUniqueQuestion.history.count(), 0)
def setUp(self): self.data = [ Poll(id=1, question="Question 1", pub_date=timezone.now()), Poll(id=2, question="Question 2", pub_date=timezone.now()), Poll(id=3, question="Question 3", pub_date=timezone.now()), Poll(id=4, question="Question 4", pub_date=timezone.now()), Poll(id=5, question="Question 5", pub_date=timezone.now()), ] bulk_create_with_history(self.data, Poll) self.data[3].question = "Updated question"
def test_bulk_create_history_rolls_back_when_last_exists(self): Poll.objects.create(id=5, question="Question 5", pub_date=now()) self.assertEqual(Poll.objects.count(), 1) self.assertEqual(Poll.history.count(), 1) with self.assertRaises(IntegrityError): bulk_create_with_history(self.data, Poll, batch_size=1) self.assertEqual(Poll.objects.count(), 1) self.assertEqual(Poll.history.count(), 1)
def test_bulk_create_history_rolls_back_when_last_exists(self): Poll.objects.create(id=5, question="Question 5", pub_date=now()) self.assertEqual(Poll.objects.count(), 1) self.assertEqual(Poll.history.count(), 1) with self.assertRaises(IntegrityError): bulk_create_with_history(self.data, Poll, batch_size=1) self.assertEqual(Poll.objects.count(), 1) self.assertEqual(Poll.history.count(), 1)
def post(self, request, *args, **kwargs): default_user = CustomUser.objects.create_superuser( "test_user", "*****@*****.**", "pass" ) # Bulk create objects with history poll_info_list = [ {"question": "1", "pub_date": date(2020, 1, 1)}, {"question": "2", "pub_date": date(2020, 1, 2)}, ] polls_to_create = [Poll(**poll_info) for poll_info in poll_info_list] bulk_create_with_history(polls_to_create, Poll, default_user=default_user) return HttpResponse(status=200)
def bulk_create(cls, license_objects, batch_size=LICENSE_BULK_OPERATION_BATCH_SIZE): """ django-simple-history functions by saving history using a post_save signal every time that an object with history is saved. However, for certain bulk operations, such as bulk_create, bulk_update, and queryset updates, signals are not sent, and the history is not saved automatically. However, django-simple-history provides utility functions to work around this. https://django-simple-history.readthedocs.io/en/2.12.0/common_issues.html#bulk-creating-and-queryset-updating """ bulk_create_with_history(license_objects, cls, batch_size=batch_size)
def update(self, instance, validated_data): user = self.context["request"].user tasks = validated_data["tasks"] models.Flow.objects.filter(task_flows__task__in=tasks).delete() flow = models.Flow.objects.create( next=validated_data["next"], created_by_user=user.username, created_by_group=user.group, ) task_flows = [ models.TaskFlow(task=task, workflow=instance, flow=flow) for task in tasks ] bulk_create_with_history(task_flows, models.TaskFlow) return instance
def __create_new_products_instance(self, df): product_images_dictioanry = self.__pop_images_dictioanry(df) new_products = [Product(FK_Shop=self.shop, Publish=True, Status='1', **row) for row in df.T.to_dict().values()] objs = bulk_create_with_history(new_products, Product, batch_size=500, default_user=self.shop.FK_ShopManager, default_change_reason=f'tag:{self.shop.ID}') self.__append_images_to_products(df, product_images_dictioanry) return new_products
def audited_bulk_create(self, objs, batch_size=None, ignore_conflicts=False, user=None): return bulk_create_with_history(objs, self.model, batch_size=batch_size, default_user=user)
def test_bulk_create_no_ids_return(self, hist_manager_mock): objects = [Place(id=1, name="Place 1")] model = Mock(objects=Mock( bulk_create=Mock(return_value=[Place(name="Place 1")]), filter=Mock(return_value=objects), )) result = bulk_create_with_history(objects, model) self.assertEqual(result, objects) hist_manager_mock().bulk_history_create.assert_called_with( objects, batch_size=None)
def create(self, validated_data): user = self.context["request"].user source = validated_data["source"] validated_data["meta"] = dict(source.meta) form = super().create(validated_data) new_form_questions = [ models.FormQuestion( sort=sort, form=form, question=form_question.question, created_by_user=user.username, created_by_group=user.group, ) for sort, form_question in enumerate(reversed( models.FormQuestion.objects.filter(form=source)), start=1) ] bulk_create_with_history(new_form_questions, models.FormQuestion) return form
def setUp(self): self.data = [ PollWithAlternativeManager(id=1, question="Question 1", pub_date=timezone.now()), PollWithAlternativeManager(id=2, question="Question 2", pub_date=timezone.now()), PollWithAlternativeManager(id=3, question="Question 3", pub_date=timezone.now()), PollWithAlternativeManager(id=4, question="Question 4", pub_date=timezone.now()), PollWithAlternativeManager(id=5, question="Question 5", pub_date=timezone.now()), ] bulk_create_with_history( self.data, PollWithAlternativeManager, )
def test_bulk_create_no_ids_return(self, hist_manager_mock): objects = [Place(id=1, name="Place 1")] model = Mock( _default_manager=Mock( bulk_create=Mock(return_value=[Place(name="Place 1")]), filter=Mock(return_value=objects), ), _meta=Mock(get_fields=Mock(return_value=[])), ) result = bulk_create_with_history(objects, model) self.assertEqual(result, objects) hist_manager_mock().bulk_history_create.assert_called_with( objects, batch_size=None, default_user=None, default_change_reason=None, default_date=None, )
def test_transaction_rolls_back_if_bulk_history_create_fails(self): with self.assertRaises(Exception): bulk_create_with_history(self.data, Poll) self.assertEqual(Poll.objects.count(), 0) self.assertEqual(Poll.history.count(), 0)
def test_bulk_create_history_with_batch_size(self): bulk_create_with_history(self.data, Poll, batch_size=2) self.assertEqual(Poll.objects.count(), 5) self.assertEqual(Poll.history.count(), 5)
def test_num_queries_when_batch_size_is_less_than_total(self): with self.assertNumQueries(6): bulk_create_with_history(self.data, Poll, batch_size=2)
def test_bulk_create_history_num_queries_is_two(self): with self.assertNumQueries(2): bulk_create_with_history(self.data, Poll)
def test_bulk_create_history(self): bulk_create_with_history(self.data, Poll) self.assertEqual(Poll.objects.count(), 5) self.assertEqual(Poll.history.count(), 5)
def test_bulk_create_fails_with_wrong_model(self): with self.assertRaises(AttributeError): bulk_create_with_history(self.data, Document) self.assertEqual(Poll.objects.count(), 0) self.assertEqual(Poll.history.count(), 0)
def test_transaction_rolls_back_if_bulk_history_create_fails(self): with self.assertRaises(Exception): bulk_create_with_history(self.data, Poll) self.assertEqual(Poll.objects.count(), 0) self.assertEqual(Poll.history.count(), 0)
def test_bulk_create_fails_with_wrong_model(self): with self.assertRaises(AttributeError): bulk_create_with_history(self.data, Document) self.assertEqual(Poll.objects.count(), 0) self.assertEqual(Poll.history.count(), 0)
def test_bulk_create_history_with_batch_size(self): bulk_create_with_history(self.data, Poll, batch_size=2) self.assertEqual(Poll.objects.count(), 5) self.assertEqual(Poll.history.count(), 5)
def test_bulk_create_history_num_queries_is_two(self): with self.assertNumQueries(2): bulk_create_with_history(self.data, Poll)
def test_bulk_create_history(self): bulk_create_with_history(self.data, Poll) self.assertEqual(Poll.objects.count(), 5) self.assertEqual(Poll.history.count(), 5)
def test_num_queries_when_batch_size_is_less_than_total(self): with self.assertNumQueries(6): bulk_create_with_history(self.data, Poll, batch_size=2)