|
26 | 26 | function_field_registry,
|
27 | 27 | )
|
28 | 28 | from creme.creme_core.models import (
|
| 29 | + CremeEntity, |
29 | 30 | CustomField,
|
30 | 31 | CustomFieldEnumValue,
|
| 32 | + FakeCivility, |
31 | 33 | FakeContact,
|
32 | 34 | FakeDocument,
|
33 | 35 | FakeFolder,
|
| 36 | + FakePosition, |
34 | 37 | FieldsConfig,
|
| 38 | + Relation, |
35 | 39 | RelationType,
|
36 | 40 | )
|
37 | 41 |
|
@@ -597,3 +601,151 @@ def __init__(self, model, value):
|
597 | 601 | TestCell(model=FakeDocument, value='title'),
|
598 | 602 | cell1
|
599 | 603 | )
|
| 604 | + |
| 605 | + def test_mixed_populate_entities01(self): |
| 606 | + "Regular fields: no FK." |
| 607 | + user = self.create_user() |
| 608 | + |
| 609 | + pos = FakePosition.objects.create(title='Pilot') |
| 610 | + create_contact = partial(FakeContact.objects.create, user=user, position_id=pos.id) |
| 611 | + contacts = [ |
| 612 | + create_contact(first_name='Nagate', last_name='Tanikaze'), |
| 613 | + create_contact(first_name='Shizuka', last_name='Hoshijiro'), |
| 614 | + ] |
| 615 | + |
| 616 | + build = partial(EntityCellRegularField.build, model=FakeContact) |
| 617 | + cells = [build(name='last_name'), build(name='first_name')] |
| 618 | + |
| 619 | + with self.assertNumQueries(0): |
| 620 | + EntityCell.mixed_populate_entities(cells=cells, entities=contacts, user=user) |
| 621 | + |
| 622 | + with self.assertNumQueries(1): |
| 623 | + contacts[0].position # NOQA |
| 624 | + |
| 625 | + def test_mixed_populate_entities02(self): |
| 626 | + "Regular fields: FK." |
| 627 | + user = self.create_user() |
| 628 | + |
| 629 | + pos = FakePosition.objects.all()[0] |
| 630 | + civ = FakeCivility.objects.all()[0] |
| 631 | + create_contact = partial( |
| 632 | + FakeContact.objects.create, user=user, position=pos, civility=civ, |
| 633 | + ) |
| 634 | + contact1 = create_contact(first_name='Nagate', last_name='Tanikaze') |
| 635 | + contact2 = create_contact(first_name='Shizuka', last_name='Hoshijiro') |
| 636 | + # NB: we refresh because the __str__() method retrieves the civility |
| 637 | + contacts = [self.refresh(contact1), self.refresh(contact2)] |
| 638 | + |
| 639 | + build = partial(EntityCellRegularField.build, model=FakeContact) |
| 640 | + cells = [ |
| 641 | + build(name='last_name'), build(name='first_name'), |
| 642 | + build(name='position'), |
| 643 | + build(name='civility__title'), |
| 644 | + ] |
| 645 | + |
| 646 | + with self.assertNumQueries(2): |
| 647 | + EntityCell.mixed_populate_entities(cells=cells, entities=contacts, user=user) |
| 648 | + |
| 649 | + with self.assertNumQueries(0): |
| 650 | + contacts[0].position # NOQA |
| 651 | + contacts[1].position # NOQA |
| 652 | + contacts[0].civility # NOQA |
| 653 | + contacts[1].civility # NOQA |
| 654 | + |
| 655 | + def test_mixed_populate_entities03(self): |
| 656 | + "Relationships." |
| 657 | + user = self.create_user() |
| 658 | + |
| 659 | + create_rt = RelationType.create |
| 660 | + loved = create_rt( |
| 661 | + ('test-subject_love', 'Is loving'), |
| 662 | + ('test-object_love', 'Is loved by'), |
| 663 | + )[1] |
| 664 | + hated = create_rt( |
| 665 | + ('test-subject_hate', 'Is hating'), |
| 666 | + ('test-object_hate', 'Is hated by'), |
| 667 | + )[1] |
| 668 | + |
| 669 | + cells = [ |
| 670 | + EntityCellRegularField.build(model=FakeContact, name='last_name'), |
| 671 | + EntityCellRelation(model=FakeContact, rtype=loved), |
| 672 | + EntityCellRelation(model=FakeContact, rtype=hated), |
| 673 | + ] |
| 674 | + |
| 675 | + create_contact = partial(FakeContact.objects.create, user=user) |
| 676 | + nagate = create_contact(first_name='Nagate', last_name='Tanikaze') |
| 677 | + shizuka = create_contact(first_name='Shizuka', last_name='Hoshijiro') |
| 678 | + izana = create_contact(first_name='Izana', last_name='Shinatose') |
| 679 | + norio = create_contact(first_name='Norio', last_name='Kunato') |
| 680 | + |
| 681 | + create_rel = partial(Relation.objects.create, user=user) |
| 682 | + create_rel(subject_entity=nagate, type=loved, object_entity=izana) |
| 683 | + create_rel(subject_entity=nagate, type=hated, object_entity=norio) |
| 684 | + create_rel(subject_entity=shizuka, type=loved, object_entity=norio) |
| 685 | + |
| 686 | + # NB: sometimes a query to get this CT is performed when the Relations |
| 687 | + # are retrieved. So we force the cache to be filled has he should be |
| 688 | + ContentType.objects.get_for_model(CremeEntity) |
| 689 | + |
| 690 | + with self.assertNumQueries(2): |
| 691 | + EntityCell.mixed_populate_entities(cells, [nagate, shizuka], user) |
| 692 | + |
| 693 | + with self.assertNumQueries(0): |
| 694 | + r1 = nagate.get_relations(loved.id, real_obj_entities=True) |
| 695 | + r2 = nagate.get_relations(hated.id, real_obj_entities=True) |
| 696 | + r3 = shizuka.get_relations(loved.id, real_obj_entities=True) |
| 697 | + r4 = shizuka.get_relations(hated.id, real_obj_entities=True) |
| 698 | + |
| 699 | + with self.assertNumQueries(0): |
| 700 | + objs1 = [r.object_entity.get_real_entity() for r in r1] |
| 701 | + objs2 = [r.object_entity.get_real_entity() for r in r2] |
| 702 | + objs3 = [r.object_entity.get_real_entity() for r in r3] |
| 703 | + objs4 = [r.object_entity.get_real_entity() for r in r4] |
| 704 | + |
| 705 | + self.assertListEqual([izana], objs1) |
| 706 | + self.assertListEqual([norio], objs2) |
| 707 | + self.assertListEqual([norio], objs3) |
| 708 | + self.assertListEqual([], objs4) |
| 709 | + |
| 710 | + def test_mixed_populate_entities04(self): |
| 711 | + "Mixed types." |
| 712 | + user = self.create_user() |
| 713 | + |
| 714 | + pos = FakePosition.objects.all()[0] |
| 715 | + create_contact = partial(FakeContact.objects.create, user=user) |
| 716 | + contacts = [ |
| 717 | + create_contact(first_name='Nagate', last_name='Tanikaze', position=pos), |
| 718 | + create_contact(first_name='Shizuka', last_name='Hoshijiro'), |
| 719 | + create_contact(first_name='Izana', last_name='Shinatose'), |
| 720 | + ] |
| 721 | + |
| 722 | + loved = RelationType.create( |
| 723 | + ('test-subject_love', 'Is loving'), |
| 724 | + ('test-object_love', 'Is loved by'), |
| 725 | + )[1] |
| 726 | + Relation.objects.create( |
| 727 | + user=user, subject_entity=contacts[0], type=loved, object_entity=contacts[2], |
| 728 | + ) |
| 729 | + |
| 730 | + build_rfield = partial(EntityCellRegularField.build, model=FakeContact) |
| 731 | + cells = [ |
| 732 | + build_rfield(name='last_name'), |
| 733 | + build_rfield(name='position'), |
| 734 | + EntityCellRelation(model=FakeContact, rtype=loved), |
| 735 | + ] |
| 736 | + |
| 737 | + # NB: sometimes a query to get this CT is performed when the Relations |
| 738 | + # are retrieved. So we force the cache to be filled has he should be |
| 739 | + ContentType.objects.get_for_model(CremeEntity) |
| 740 | + |
| 741 | + # Drop caches |
| 742 | + contacts = [self.refresh(c) for c in contacts] |
| 743 | + |
| 744 | + with self.assertNumQueries(3): |
| 745 | + EntityCell.mixed_populate_entities(cells, contacts, user) |
| 746 | + |
| 747 | + with self.assertNumQueries(0): |
| 748 | + contacts[0].position # NOQA |
| 749 | + |
| 750 | + with self.assertNumQueries(0): |
| 751 | + contacts[0].get_relations(loved.id, real_obj_entities=True) |
0 commit comments