models.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. """ Catalog models """
  2. from django.conf import settings
  3. from django.db import models
  4. from django.core.urlresolvers import reverse
  5. from django.utils.text import Truncator
  6. from sorl import thumbnail
  7. from catalog.constants import SHIPPING_TYPES, INSTATE, REGULAR, SHIPPING_METHODS
  8. from catalog.managers import (
  9. ItemManager,
  10. PersonManager,
  11. SubscriptionManager,
  12. ZipCodeManager,
  13. )
  14. from pbp_core.models import OperationalTable
  15. from pbp_core.slugify import unique_slugify
  16. MEDIA_DIRECTORY = settings.MEDIA_ROOT
  17. class Item(OperationalTable):
  18. """ Item model """
  19. title = models.CharField(max_length=50)
  20. long_description = models.TextField(blank=True, null=True)
  21. synopsis = models.CharField(max_length=200, blank=True, null=True)
  22. image = thumbnail.ImageField(upload_to="images/sorl", blank=True, null=True)
  23. price = models.DecimalField(max_digits=7, decimal_places=2)
  24. # shipping cost for one item
  25. shipping_cost = models.DecimalField(max_digits=7, decimal_places=2)
  26. # shipping cost for each item after 1.
  27. shipping_cost_multiple = models.DecimalField(max_digits=7, decimal_places=2)
  28. subclass_type = models.CharField(max_length=200, editable=False)
  29. sku = models.SlugField(max_length=20, unique=True)
  30. # logical delete Might cause confusion if they want to reuse
  31. # the SKU again since that is required to be unique.
  32. deleted = models.BooleanField(default=False)
  33. featured = models.BooleanField(default=False)
  34. tax_free = models.BooleanField(default=False)
  35. objects = ItemManager()
  36. def __unicode__(self):
  37. """ unicode repr of class """
  38. return unicode(self.title)
  39. def save(self, *args, **kwargs):
  40. """ save the model """
  41. # save what kind we are.
  42. self.subclass_type = self.__class__.__name__.lower()
  43. super(Item, self).save(*args, **kwargs)
  44. def child(self):
  45. """ get the child """
  46. return getattr(self, self.subclass_type)
  47. @property
  48. def is_book(self):
  49. """ are we a book """
  50. return self.subclass_type == Book.__name__.lower()
  51. @property
  52. def is_movie(self):
  53. """ are we a movie """
  54. return self.subclass_type == Movie.__name__.lower()
  55. @property
  56. def is_map(self):
  57. """ is it a map """
  58. return self.subclass_type == Map.__name__.lower()
  59. @property
  60. def is_subscription(self):
  61. """ is subscription """
  62. return self.subclass_type == Subscription.__name__.lower()
  63. @property
  64. def category(self):
  65. """ Return a string name for the category the item is in."""
  66. if self.is_book():
  67. return "book"
  68. elif self.is_movie():
  69. return "movie"
  70. elif self.is_map():
  71. return "map"
  72. elif self.is_subscription():
  73. return "subscription"
  74. else:
  75. return None
  76. @property
  77. def edit_link(self):
  78. """ get the edit link """
  79. return self.child().edit_link
  80. def get_absolute_url(self):
  81. """ get absolute url """
  82. return reverse("item_detail", kwargs={"sku": self.sku})
  83. @property
  84. def short_description(self):
  85. return Truncator(self.long_description).words(25, truncate=" ...")
  86. @property
  87. def description(self):
  88. return self.long_description
  89. class Person(OperationalTable):
  90. """ Person Model """
  91. name = models.CharField(max_length=60)
  92. slug = models.SlugField(max_length=60, unique=True)
  93. title = models.CharField(max_length=60, null=True, blank=True, default="")
  94. image = thumbnail.ImageField(upload_to="images/sorl", blank=True, null=True)
  95. description = models.TextField(null=True, blank=True, default="")
  96. # logical delete Might cause confusion if they want to reuse
  97. # the SKU again since that is required to be unique.
  98. deleted = models.BooleanField(default=False)
  99. objects = PersonManager()
  100. def __repr__(self):
  101. return u"{0}(name={1}".format(self.__class__, self.name)
  102. def __str__(self):
  103. return (
  104. u"{0}".format(self.name)
  105. if not self.title
  106. else u"{0}, {1}".format(self.name, self.title)
  107. )
  108. @property
  109. def edit_link(self):
  110. """ get the edit link """
  111. try:
  112. return reverse("person_edit", kwargs={"person_slug": self.slug})
  113. except Exception, e:
  114. print e
  115. def save(self, *args, **kwargs):
  116. if not self.slug:
  117. unique_slugify(self, self.name)
  118. super(Person, self).save(*args, **kwargs)
  119. class Book(Item):
  120. """ Book model """
  121. subtitle = models.CharField(max_length=100, blank=True, null=True)
  122. authors = models.ManyToManyField(Person, blank=True, null=True)
  123. editors = models.CharField(max_length=200, blank=True, null=True)
  124. illustrator = models.CharField(max_length=200, blank=True, null=True)
  125. publisher = models.CharField(max_length=200, blank=True, null=True)
  126. printer = models.CharField(max_length=200, blank=True, null=True)
  127. publish_date = models.CharField(max_length=20, blank=True, null=True)
  128. edition = models.CharField(max_length=50, blank=True, null=True)
  129. features = models.CharField(max_length=100, blank=True, null=True)
  130. dimensions = models.CharField(max_length=20, blank=True, null=True)
  131. pages = models.IntegerField(blank=True, null=True)
  132. isbn = models.CharField(max_length=20, blank=True, null=True)
  133. library_of_congress_number = models.CharField(max_length=20, blank=True, null=True)
  134. genre = models.CharField(max_length=100, blank=True, null=True)
  135. objects = ItemManager()
  136. @property
  137. def edit_link(self):
  138. """ get the edit link """
  139. return reverse("catalog_edit_book", kwargs={"sku": self.sku})
  140. class Movie(Item):
  141. """ Movie model """
  142. producer = models.CharField(max_length=200, blank=True, null=True)
  143. music = models.CharField(max_length=200, blank=True, null=True)
  144. runtime_minutes = models.IntegerField(blank=True, null=True)
  145. format = models.CharField(max_length=20, blank=True, null=True)
  146. region = models.CharField(max_length=50, blank=True, null=True)
  147. sound = models.CharField(max_length=50, blank=True, null=True)
  148. language = models.CharField(max_length=50, blank=True, null=True)
  149. captioning = models.CharField(max_length=50, blank=True, null=True)
  150. genre = models.CharField(max_length=100, blank=True, null=True)
  151. objects = ItemManager()
  152. @property
  153. def edit_link(self):
  154. """ get the edit link """
  155. return reverse("catalog_edit_movie", kwargs={"sku": self.sku})
  156. class Map(Item):
  157. """ Map model"""
  158. dimensions = models.CharField(max_length=20, blank=True, null=True)
  159. objects = ItemManager()
  160. @property
  161. def edit_link(self):
  162. """ get Edit link """
  163. return reverse("catalog_edit_map", kwargs={"sku": self.sku})
  164. class Subscription(Item):
  165. """ Subscriptions are items and are operational tables (created by,
  166. time, ect).
  167. """
  168. shipping_type = models.CharField(
  169. max_length=10, choices=SHIPPING_TYPES, default=INSTATE
  170. )
  171. shipping_method = models.CharField(
  172. max_length=20, choices=SHIPPING_METHODS, default=REGULAR
  173. )
  174. duration = models.IntegerField()
  175. renewal = models.BooleanField(default=False)
  176. objects = SubscriptionManager()
  177. @property
  178. def edit_link(self):
  179. """ get the edit link"""
  180. return reverse("catalog_edit_subscription", kwargs={"sku": self.sku})
  181. class ZipCode(OperationalTable):
  182. """ Zip code model """
  183. zipcode = models.CharField(max_length=9, unique=True)
  184. city = models.CharField(max_length=64, blank=True, null=True)
  185. state = models.CharField(max_length=2, blank=True, null=True)
  186. county = models.CharField(max_length=64, blank=True, null=True)
  187. deleted = models.BooleanField(default=False)
  188. objects = ZipCodeManager()
  189. def __unicode__(self):
  190. """ unicode repr of class """
  191. return unicode(self.zipcode)