Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Concepts in Django

Decouple Django apps with business logic to have better reusability.

  • Login to see the comments

Concepts in Django

  1. 1. Concepts in Django Douwe van der Meij Goldmund, Wyldebeast & Wunderliebe vandermeij@gw20e.com github.com/douwevandermeij
  2. 2. Project INSTALLED_APPS = ( ... 'crm', 'webshop', ... )
  3. 3. Dependencies ● Inter-app foreign key constraint crm Customer Project account_nr ● How to reuse webshop without crm? Order order_nr webshop OrderLine
  4. 4. Concepts Define: ● Producers ○ Contain data Producer ● Consumers ○ Don’t contain data ○ Need a producer Consumer
  5. 5. Customer concept The concept we’re talking about: ● A customer ○ Has a number
  6. 6. Applications with concepts crm Producer Customer Project account_nr webshop Consumer Customer number Order OrderLine
  7. 7. Define Producers Conceptname CONCEPTS = { Producer model 'CustomerConcept': { 'crm.models.Customer': { 'number': 'account_nr', Field mapping }, }, } ● Map to existing models
  8. 8. Consume class Order(models.Model): customer = models.ForeignKey(CustomerConcept) order_nr = models.IntegerField()
  9. 9. Dependencies crm ● ORM level Customer Customer CustomerConcept concepts Order webshop Project
  10. 10. Dependencies crm Customer Order webshop Project ● Database level
  11. 11. The magic (1/4) from django.conf import settings for concept_name, mapping in settings.CONCEPTS.items(): for klass, fields in mapping.items(): ... ● The concepts app ○ Loops over settings.CONCEPTS
  12. 12. The magic (2/4) from concepts.util import load_class ● Create a dynamic class ● With in ... concept = type( proxy = True Meta concept_name, (load_class(klass),), { '__module__': __name__, 'Meta': type('Meta', (), {'proxy': True}), }, ) ...
  13. 13. The magic (3/4) ... for _property, _field in fields.items(): if not hasattr(concept, _property): setattr( concept, _property, property( lambda self: getattr(self, _field), lambda self, value: setattr(self, _field, value), ), ) ... ● Create properties for all fields
  14. 14. The magic (4/4) import concepts ● Bind the concept to the concepts module ... setattr(concepts, concept_name, concept)
  15. 15. Conclusion ● Concepts make apps reusable ○ Without dependencies ● The only dependency ○ Is a concept ● The concept producer ○ You may choose yourself ○ On existing apps
  16. 16. Try it yourself ● github.com / douwevandermeij / concepts_example ● Related work ○ Django Swappable Models ■ Like swapping auth.User model in 1.5+ ○ Zope Component Architecture ■ Interfaces: implement/adapt
  17. 17. Thank you! Douwe van der Meij Goldmund, Wyldebeast & Wunderliebe vandermeij@gw20e.com github.com/douwevandermeij

×