Course references ***************** Courses are referenced by certificate courses. :Test-Layer: functional We can be sure, that when removing courses or references to them, other data will be handled in a way we expect. That is, * when we remove a course, we want all references to it be removed as well * when we remove a reference to a course, nothing else should be touched but only this very reference. As correct deletion of references needs support of catalogs (we lookup catalogs to find references), we need a fully blown ZODB here, including an instance of :class:`waeup.app.University`, as this is our `ISite` object where the catalogs are stored. We create a complete university tree, starting with a :class:`University` instance and going down to courses, certificats and course certificates: >>> from waeup.app import University >>> root = getRootFolder() >>> root['app'] = University() We have to set the site, to enable proper working of catalogs and `IObjectRemoved` handlers: >>> from zope.app.component.hooks import setSite >>> setSite(root['app']) >>> from zope.component import createObject >>> faculty = createObject('waeup.Faculty') >>> faculty.code = 'FAC' >>> root['app']['faculties'].addFaculty(faculty) >>> fac = root['app']['faculties']['FAC'] >>> dept = createObject('waeup.Department') >>> dept.code = 'DEPT' >>> root['app']['faculties']['FAC'].addDepartment(dept) >>> course = createObject('waeup.Course') >>> course.code = 'CRS1' >>> fac['DEPT'].courses.addCourse(course) Now let's add another department, which will also hold a course: >>> dept2 = createObject('waeup.Department') >>> dept2.code = 'DEPT2' >>> root['app']['faculties']['FAC'].addDepartment(dept2) >>> course = createObject('waeup.Course') >>> course.code = 'CRS2' >>> fac['DEPT2'].courses.addCourse(course) Finally, we add a certificate with references (certificate courses) to the created courses: >>> cert = createObject('waeup.Certificate') >>> cert.code = 'CERT' >>> fac['DEPT'].certificates.addCertificate(cert) >>> fac['DEPT'].certificates['CERT'].addCourseRef( ... fac['DEPT'].courses['CRS1']) >>> fac['DEPT'].certificates['CERT'].addCourseRef( ... fac['DEPT2'].courses['CRS2']) We add the latter course again, but this time for the second level: >>> fac['DEPT'].certificates['CERT'].addCourseRef( ... fac['DEPT2'].courses['CRS2'], level=200) So, we have three references in our certificate to two different courses stored somewhere in the application: >>> list(fac['DEPT'].certificates['CERT']) [u'CRS1_100', u'CRS2_100', u'CRS2_200'] Both, the courses themselves and the references to them, are the same (not only equal): >>> a = root['app']['faculties']['FAC']['DEPT'] >>> b1 = a.courses['CRS1'] >>> b2 = a.certificates['CERT']['CRS1_100'].course >>> b1 is b2 True If we remove the course, also the reference to it in the cert course will be gone: >>> list(a.certificates['CERT']) [u'CRS1_100', u'CRS2_100', u'CRS2_200'] >>> list(a.courses) [u'CRS1'] >>> del root['app']['faculties']['FAC']['DEPT'].courses['CRS1'] >>> list(a.certificates['CERT']) [u'CRS2_100', u'CRS2_200'] >>> list(a.courses) [] If we remove a reference, this will not touch the referenced course nor other references: >>> del fac['DEPT'].certificates['CERT']['CRS2_200'] >>> list(a.certificates['CERT']) [u'CRS2_100'] >>> list(fac['DEPT2'].courses) [u'CRS2']