Açıklama Yok

models.py 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. from django.db import models
  4. from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
  5. from django.db.utils import IntegrityError
  6. from django.utils.text import Truncator
  7. import re
  8. #import logging
  9. #logger = logging.getLogger('console')
  10. unique_constraint_re = re.compile(r'^UNIQUE\s+constraint\s+failed:(.*)$', re.IGNORECASE)
  11. class ModelEx(models.Model):
  12. class Meta:
  13. abstract = True
  14. def get_duplicate_key_error_dict(self, fields):
  15. return {NON_FIELD_ERRORS: 'Duplicate value for %s' % ', '.join(fields)}
  16. def save(self, *args, **kwargs):
  17. try:
  18. super(ModelEx, self).save(*args, **kwargs)
  19. except IntegrityError as e:
  20. match = unique_constraint_re.search(e.message)
  21. if match:
  22. fields = [x.strip().split('.')[-1] for x in match.group(1).split(',')]
  23. raise ValidationError(self.get_duplicate_key_error_dict(fields))
  24. else:
  25. raise
  26. class FeedCategory(ModelEx):
  27. name = models.CharField(max_length=50, unique=True)
  28. description = models.CharField(max_length=255, blank=True)
  29. days_required = models.PositiveIntegerField(default=366)
  30. class Meta:
  31. verbose_name = 'Category'
  32. verbose_name_plural = 'Categories'
  33. def get_duplicate_key_error_dict(self, fields):
  34. if fields[0] == 'name':
  35. return {'name': 'There is already a category with this name'}
  36. else:
  37. return super(FeedCategory, self).get_duplicate_key_error_dict(fields)
  38. @property
  39. def status(self):
  40. last_day = 0
  41. total_missing = 0
  42. missing_days = []
  43. for item in FeedItem.objects.filter(feed_category=self).order_by('feed_category_id', 'day_number'):
  44. day = item.day_number
  45. missing_count = day - last_day - 1
  46. total_missing += missing_count
  47. # The unique key and order_by on FeedItem ensure that missing_count
  48. # cannot be less than 0.
  49. if missing_count == 1:
  50. missing_days.append(str(day - 1))
  51. elif missing_count > 1:
  52. missing_days.append('{0}-{1}'.format(last_day + 1, day - 1))
  53. last_day = day
  54. missing_count = self.days_required - last_day
  55. if missing_count > 0:
  56. total_missing += missing_count
  57. if missing_count == 1:
  58. missing_days.append(str(self.days_required))
  59. elif missing_count > 1:
  60. missing_days.append('{0}-{1}'.format(last_day + 1, self.days_required))
  61. if missing_days:
  62. return "WARNING: Missing {0} day{1}: {2}".format(total_missing, '' if total_missing == 1 else 's', ', '.join(missing_days))
  63. else:
  64. return "Complete"
  65. def __unicode__(self):
  66. return self.name
  67. class FeedItem(ModelEx):
  68. feed_category = models.ForeignKey(FeedCategory, on_delete=models.CASCADE)
  69. day_number = models.PositiveIntegerField()
  70. message_text = models.CharField(max_length=160)
  71. class Meta:
  72. verbose_name = 'Item'
  73. verbose_name_plural = 'Items'
  74. unique_together = ('feed_category', 'day_number')
  75. def get_duplicate_key_error_dict(self, fields):
  76. return {'day_number': 'There is already an item with this day number'}
  77. def __unicode__(self):
  78. return u'{0}: {1}'.format(self.day_number, Truncator(self.message_text).chars(20))