You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

abstract_models.py 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import hashlib
  2. import random
  3. from django.db import models
  4. from django.utils.translation import ugettext_lazy as _
  5. from django.core.urlresolvers import reverse
  6. from oscar.core.compat import AUTH_USER_MODEL
  7. class AbstractWishList(models.Model):
  8. """
  9. Represents a user's wish lists of products.
  10. A user can have multiple wish lists, move products between them, etc.
  11. """
  12. # Only authenticated users can have wishlists
  13. owner = models.ForeignKey(AUTH_USER_MODEL, related_name='wishlists',
  14. verbose_name=_('Owner'))
  15. name = models.CharField(verbose_name=_('Name'), default=_('Default'),
  16. max_length=255)
  17. #: This key acts as primary key and is used instead of an int to make it
  18. #: harder to guess
  19. key = models.CharField(_('Key'), max_length=6, db_index=True, unique=True,
  20. editable=False)
  21. # Oscar core does not support public or shared wishlists at the moment, but
  22. # all the right hooks should be there
  23. PUBLIC, PRIVATE, SHARED = ('Public', 'Private', 'Shared')
  24. VISIBILITY_CHOICES = (
  25. (PRIVATE, _('Private - Only the owner can see the wish list')),
  26. (SHARED, _('Shared - Only the owner and people with access to the'
  27. ' obfuscated link can see the wish list')),
  28. (PUBLIC, _('Public - Everybody can see the wish list')),
  29. )
  30. visibility = models.CharField(_('Visibility'), max_length=20,
  31. default=PRIVATE, choices=VISIBILITY_CHOICES)
  32. # Convention: A user can have multiple wish lists. The last created wish
  33. # list for a user shall be her "default" wish list.
  34. # If an UI element only allows adding to wish list without
  35. # specifying which one , one shall use the default one.
  36. # That is a rare enough case to handle it by convention instead of a
  37. # BooleanField.
  38. date_created = models.DateTimeField(
  39. _('Date created'), auto_now_add=True, editable=False)
  40. def __unicode__(self):
  41. return u"%s's Wish List '%s'" % (self.owner, self.name)
  42. def save(self, *args, **kwargs):
  43. if not self.pk or kwargs.get('force_insert', False):
  44. self.key = self.__class__.random_key()
  45. super(AbstractWishList, self).save(*args, **kwargs)
  46. @classmethod
  47. def random_key(cls, length=6):
  48. """
  49. Get a unique random generated key based on SHA-1 and owner
  50. """
  51. while True:
  52. key = hashlib.sha1(str(random.random())).hexdigest()[:length]
  53. if not cls._default_manager.filter(key=key).exists():
  54. return key
  55. def is_allowed_to_see(self, user):
  56. if self.visibility in (self.PUBLIC, self.SHARED):
  57. return True
  58. else:
  59. return user == self.owner
  60. def is_allowed_to_edit(self, user):
  61. # currently only the owner can edit her wish list
  62. return user == self.owner
  63. class Meta:
  64. ordering = ('owner', 'date_created', )
  65. verbose_name = _('Wish List')
  66. abstract = True
  67. def get_absolute_url(self):
  68. return reverse('customer:wishlists-detail', kwargs={
  69. 'key': self.key})
  70. def add(self, product):
  71. """
  72. Add a product to this wishlist
  73. """
  74. lines = self.lines.filter(product=product)
  75. if len(lines) == 0:
  76. self.lines.create(
  77. product=product, title=product.get_title())
  78. else:
  79. line = lines[0]
  80. line.quantity += 1
  81. line.save()
  82. class AbstractLine(models.Model):
  83. """
  84. One entry in a wish list. Similar to order lines or basket lines.
  85. """
  86. wishlist = models.ForeignKey('wishlists.WishList', related_name='lines',
  87. verbose_name=_('Wish List'))
  88. product = models.ForeignKey(
  89. 'catalogue.Product', verbose_name=_('Product'),
  90. related_name='wishlists_lines', on_delete=models.SET_NULL,
  91. blank=True, null=True)
  92. quantity = models.PositiveIntegerField(_('Quantity'), default=1)
  93. #: Store the title in case product gets deleted
  94. title = models.CharField(_("Title"), max_length=255)
  95. def __unicode__(self):
  96. return u'%sx %s on %s' % (self.quantity, self.title,
  97. self.wishlist.name)
  98. def get_title(self):
  99. if self.product:
  100. return self.product.get_title()
  101. else:
  102. return self.title
  103. class Meta:
  104. abstract = True
  105. verbose_name = _('Wish list line')
  106. unique_together = (('wishlist', 'product'), )