models.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. from django.contrib.auth.models import User
  2. from django.db import models
  3. from django.utils.encoding import force_unicode
  4. from django.utils.translation import ugettext_lazy as _
  5. from django.core.urlresolvers import reverse
  6. from django.conf import settings
  7. import base64
  8. import os
  9. def generate_url():
  10. key = base64.urlsafe_b64encode(os.urandom(16))[:20]
  11. return key
  12. class State(models.Model):
  13. name = models.CharField(
  14. max_length = 50,
  15. verbose_name = _('name')
  16. )
  17. def __unicode__(self):
  18. return self.name
  19. class Meta:
  20. verbose_name = _('state')
  21. verbose_name_plural = _('states')
  22. ordering = ['name']
  23. class Party(models.Model):
  24. name = models.CharField(
  25. max_length = 50,
  26. verbose_name = _('name')
  27. )
  28. shortname = models.CharField(
  29. max_length = 10,
  30. verbose_name = _('shortname')
  31. )
  32. def __unicode__(self):
  33. return self.shortname
  34. class Meta:
  35. verbose_name = _('party')
  36. verbose_name_plural = _('parties')
  37. ordering = ['name']
  38. class Category(models.Model):
  39. name = models.CharField(
  40. max_length = 50,
  41. verbose_name = _('name')
  42. )
  43. def __unicode__(self):
  44. return self.name
  45. class Meta:
  46. verbose_name = _('category')
  47. verbose_name_plural = _('categories')
  48. class Politician(models.Model):
  49. user = models.ForeignKey(
  50. User,
  51. verbose_name = _('user')
  52. )
  53. first_name = models.CharField(
  54. max_length = 100,
  55. blank = True,
  56. null = True,
  57. verbose_name = _('first_name')
  58. )
  59. last_name = models.CharField(
  60. max_length = 100,
  61. blank = True,
  62. null = True,
  63. verbose_name = _('last_name')
  64. )
  65. email = models.EmailField(
  66. blank = True,
  67. null = True,
  68. verbose_name = _('email')
  69. )
  70. image = models.ImageField(
  71. upload_to = 'politicians/',
  72. null = True,
  73. blank = True,
  74. verbose_name = _('image')
  75. )
  76. is_member_of_parliament = models.BooleanField(
  77. default = False,
  78. verbose_name = _('is_member_of_parliament')
  79. )
  80. past_contributions = models.TextField(
  81. blank = True,
  82. verbose_name = _('past_contributions')
  83. )
  84. future_plans = models.TextField(
  85. blank = True,
  86. verbose_name = _('future_plans')
  87. )
  88. unique_key = models.CharField(
  89. max_length = 20,
  90. verbose_name = _('unique_key'),
  91. default = generate_url
  92. )
  93. state = models.ForeignKey(
  94. State,
  95. null = True,
  96. blank = True,
  97. verbose_name = _('state')
  98. )
  99. party = models.ForeignKey(
  100. Party,
  101. null = True,
  102. blank = True,
  103. verbose_name = _('party')
  104. )
  105. party_other = models.CharField(
  106. max_length = 50,
  107. null = True,
  108. blank = True,
  109. verbose_name = _('party_other')
  110. )
  111. def __unicode__(self):
  112. return u'%s %s' % (self.first_name, self.last_name)
  113. @classmethod
  114. def get_politicians_by_category(cls, category_id, input_value, order='-accordance'):
  115. return cls.objects.filter(statistic__category_id=category_id).extra(
  116. select={'accordance':'core_statistic_compare(value::integer, %d::integer)' % input_value}
  117. ).order_by(order)
  118. @property
  119. def party_name(self):
  120. if self.party:
  121. return self.party.name
  122. elif self.party_other:
  123. return self.party_other
  124. else:
  125. return '-'
  126. @property
  127. def party_short(self):
  128. if self.party:
  129. return self.party.shortname
  130. elif self.party_other:
  131. return self.party_other
  132. else:
  133. return '-'
  134. @property
  135. def state_name(self):
  136. if self.state:
  137. return self.state.name
  138. else:
  139. return '-'
  140. def get_details(self):
  141. if not self.party and not self.state:
  142. return ''
  143. elif self.party and not self.state:
  144. return '(%s)' % self.party_short
  145. elif not self.party and self.state:
  146. return '(%s)' % self.state_name
  147. else:
  148. return '(%s, %s)' % (self.state_name, self.party_short)
  149. @property
  150. def unique_url(self):
  151. return '%s%s' % (
  152. settings.BASE_URL,
  153. reverse('politician_edit', args=[self.unique_key])
  154. )
  155. class Meta:
  156. verbose_name = _('politician')
  157. verbose_name_plural = _('politicians')
  158. class LinkType(models.Model):
  159. icon = models.ImageField(
  160. upload_to = 'icons/',
  161. verbose_name = _('icon')
  162. )
  163. name = models.CharField(
  164. max_length = 50,
  165. verbose_name = _('name')
  166. )
  167. class Meta:
  168. verbose_name = _('link_type')
  169. verbose_name_plural = _('link_types')
  170. class Link(models.Model):
  171. type = models.ForeignKey(
  172. LinkType,
  173. verbose_name = _('type')
  174. )
  175. politician = models.ForeignKey(
  176. Politician,
  177. verbose_name = _('politician')
  178. )
  179. url = models.URLField(
  180. verbose_name = _('url')
  181. )
  182. class Meta:
  183. verbose_name = _('link')
  184. verbose_name_plural = _('links')
  185. class Question(models.Model):
  186. preferred_answer = models.IntegerField(
  187. verbose_name = _('preferred_answer')
  188. )
  189. question_number = models.IntegerField(
  190. verbose_name = _('question_number')
  191. )
  192. category = models.ForeignKey(
  193. Category,
  194. verbose_name = _('category')
  195. )
  196. text = models.TextField(
  197. verbose_name = _('text')
  198. )
  199. description = models.TextField(
  200. null = True,
  201. blank = True,
  202. verbose_name = _('description')
  203. )
  204. class Meta:
  205. verbose_name = _('question')
  206. verbose_name_plural = _('questions')
  207. ordering = ['category__name']
  208. class Answer(models.Model):
  209. question = models.ForeignKey(
  210. Question,
  211. verbose_name = _('question')
  212. )
  213. politician = models.ForeignKey(
  214. Politician,
  215. verbose_name = _('politician')
  216. )
  217. agreement_level = models.IntegerField(
  218. verbose_name = _('agreement_level')
  219. )
  220. note = models.TextField(
  221. verbose_name = _('note')
  222. )
  223. class Meta:
  224. verbose_name = _('answer')
  225. verbose_name_plural = _('answers')
  226. class Statistic(models.Model):
  227. politician = models.ForeignKey(
  228. Politician,
  229. verbose_name = _('politician')
  230. )
  231. category = models.ForeignKey(
  232. Category,
  233. verbose_name = _('category')
  234. )
  235. value = models.IntegerField(
  236. verbose_name = _('value')
  237. )
  238. @classmethod
  239. def get_accordance(cls, politician_id, category_id, input_value):
  240. statistic = cls.objects.filter(politician_id=politician_id, category_id=category_id).extra(
  241. select={
  242. 'accordance' : 'core_statistic_compare(value::integer, %d::integer)' % input_value
  243. }
  244. ).first()
  245. return (statistic.accordance if statistic else 0)
  246. @classmethod
  247. def get_statistics_by_politician(cls, politician_id):
  248. return cls.objects.raw('''
  249. SELECT
  250. s.*,
  251. core_statistic_compare(s.value::integer, AVG(q.preferred_answer*10)::integer) AS accordance
  252. FROM core_statistic AS s
  253. JOIN core_category AS c ON (
  254. s.category_id = c.id
  255. )
  256. JOIN core_question AS q ON (
  257. c.id = q.category_id
  258. )
  259. WHERE s.politician_id = %s
  260. GROUP BY s.id, q.category_id, c.name
  261. ORDER BY c.name
  262. ''', [politician_id])
  263. class Meta:
  264. verbose_name = _('statistic')
  265. verbose_name_plural = _('statistics')