Chris Moffitt avatar Chris Moffitt committed b2a77d0

Adding some notes to the docs about how to use mixins to modify the admin.

Comments (0)

Files changed (3)

docs/custom-admin.txt

 .. Note::
     These changes must be included in an application that is listed after 
     all the other Satchmo Apps in ``INSTALLED_APPS``
+
+Using Mix-ins to customize the admin
+------------------------------------
+
+Mix-ins are a very powerful feature available in python that allow for
+advanced customization of Satchmo.  With mix-ins you can add arbitrary
+elements (functions, model attributes, etc...) to any class/model.
+The full uses of mix-ins are outside the scope of this document but
+let’s start with an example.
+
+Suppose you want to show product SKUs of all the products in an order
+on the Product Orders page. The screenshot below shows you what the current
+order screen looks like:
+
+.. image:: /images/order-screen2.png
+
+We will modify it to show all the skus in an order like this:
+
+.. image:: /images/order-screen1.png
+
+
+Here is a chunk of code that would create a list of skus for a given order::
+
+        def order_sku(self):
+            allsku = ''
+            for item in self.orderitem_set.all():
+                allsku += "%s<br />" % item.product.sku
+            return allsku
+        order_sku.allow_tags = True
+        order_sku.short_description = "Order SKUs"
+
+
+You could then add ‘order_sku’ to the list display of Order.  The
+problem is, where do you put the chunk of code listed above?  You
+could add it to the Order models but that would be forking Satchmo and
+later when it was time to upgrade to the next version of Satchmo
+things could be much more difficult.  The solution is mix-ins.
+
+Mix-ins allow you to dynamically change the inheritance of a class.
+We will change Orders from looking like this::
+
+    class Order(models.Model):
+
+to this::
+    
+    class Order(models.Model, ourNewClass):
+    
+In order to accomplish this without actually modifying existing Satchmo done, you
+can put order_sku in a class::
+
+    class OrderExtend:
+        def order_sku(self):
+            allsku = ''
+            for item in self.orderitem_set.all():
+                allsku += "%s<br />" % item.product.sku
+            return allsku
+        order_sku.allow_tags = True
+        order_sku.short_description = "Order SKUs"
+
+and adding::
+
+    Order.__bases__ += (OrderExtend,)
+    
+The last bit takes the __bases__ of Order (which are its base
+inheritance classes) and adds OrderExtend to it.  Because Order now
+inherits from OrderExtend we can use order_sku.  To make skus show up
+in the admin we create ``localsite/admin.py`` and put all of our code in
+it so it looks like this::
+
+    from django.contrib import admin
+    from django.db import models
+    from satchmo_store.shop.models import Order, OrderItem
+    from satchmo_store.shop.admin import OrderOptions
+
+    class OrderExtend:
+        def order_sku(self):
+            allsku = ''
+            for item in self.orderitem_set.all():
+                allsku += "%s<br />" % item.product.sku
+            return allsku
+        order_sku.allow_tags = True
+        order_sku.short_description = "Order SKUs"
+
+    Order.__bases__ += (OrderExtend,)
+
+    admin.site.unregister(Order)
+
+    class CustomOrderAdmin(OrderOptions):
+        list_display = ('id', 'order_sku', 'contact', 'time_stamp',
+                        'order_total', 'balance_forward', 'status', 
+                        'invoice', 'packingslip','shippinglabel')
+
+    admin.site.register(Order, CustomOrderAdmin)
+
+Obviously you could do a lot more with mix-ins. You can add arbitray functions
+and attributes to any model and any class.  A much longer
+explaination that is not django specific but has more examples (and the document used as a reference
+for writing this up) can be found `here <http://www.linuxjournal.com/node/4540/print>`_
Add a comment to this file

docs/images/order-screen1.png

Added
New image
Add a comment to this file

docs/images/order-screen2.png

Added
New image
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.