Django generic relations in test fixtures

Το Django framework περιλαμβάνει μια λειτουργικότητα που την ονομάζει content types. Το content types framework επιτρέπει, μεταξύ άλλων, στο Django να έχει λειτουργίες όπως τα generic relations

Ο τρόπος λειτουργίας είναι σχετικά απλός. Το content types framework βασικά λέει:

Για κάθε μοντέλο του ORM φτιάχνω μια εγγραφή στον πίνακα django_content_type που περιέχει ,μεταξύ άλλων, το όνομα του application και το όνομα του μοντέλου και φυσικά ένα ID.

Το generic relationship επιτρέπει σε ένα μοντέλο να έχει ένα foreign key σε ένα οποιοδήποτε άλλο μοντέλο στο django. Αυτό το επιτυγχάνει προσθέτοντας 2 πεδία στο μοντέλο που περιέχει το foreign key. Το content type και το id.

Έστω οτι έχουμε ένα μοντέλο Comment. Μιας και θέλουμε το Comment μπορεί να μπορεί να αναρτηθεί σε διάφορα μοντέλα (πχ Story, άλλα Comments, News, Product κλπ) χρησιμοποιούμε generic relations. Αν ονομάζαμε το πεδίο αυτό “commenting_on” τότε όταν ζητήσουμε απο το django να μας δώσει το object στο οποίο δείχνει το commenting_on, το Django θα δεί το content_type πεδίο, θα αναζητήσει την αντίστοιχη εγγραφή στον πίνακα django_content_types και θα βρεί το application και model στο οποίο αναφερόμαστε. Γνωρίζοντας αυτά, και αφού έχει και το id μπορεί έυκολα να μας επιστρέψει ένα instance του μοντέλου.

Εδώ πρέπει να αναφέρω μιά ακόμα τεχνολογία του django. Το serialization framework που μας επιτρέπει να κάνουμε serialize και να εξάγουμε τα δεδομένα μας σε αρχείο κειμένου (YAML,XML, JSON και άλλα) όπως και να τα εισάγουμε στην βάση μας απο ένα serialized αρχείο.

Τα serialization είναι εξαιρετικά χρήσιμο σε πάρα πολλές περιπτώσεις, με πιθανότατα πιο συχνή το Testing framework, όπου μας δίνει την δυνατότητα πριν απο κάθε test να φορτώνουμε κάποια γνωστά δεδομένα στην database.

Όταν κάνουμε serialize ένα μοντέλο που περιέχει generic foreign keys, οι serializers του Django απλά καταγράφουν το content_type_id και το object_id.

Εδώ δημιουργείται το πρόβλημα.

Τα content_types φτιάχνονται κατα το syncdb (κάτι που γίνεται στην αρχή του test runner ) και τα id που θα πάρουν εξαρτώνται απο την σειρά με την οποία θα διαβάσει τις εφαρμογές και τα μοντέλα το django. Τα test fixtures που φτιάξαμε νωρίτερα μεσω του serializer θα βγούν άχρηστα όταν για κάποιο λόγω αλλάξουν τα id των content types, και τα test μας θα αρχίσουν να σπάνε και χωρίς εμείς να ξέρουμε γιατί (αφού τα φόρτωσε χωρίς πρόβλημα).

Δυστυχώς δεν υπάρχει καλή λύση για αυτό το πρόβλημα.

Μια προσωρινή αλλα πολύ άσχημη λύση είναι στο test να κάνουμε lookup για το σωστό content type και να το αλλάζουμε on-the-fly. Yuck.

Είμαι γκαντέμης ή απλά άτυχος? :p

Comments !

blogroll

social