title: Is it better to change the db schema?
body: <p>I'm building a web app with django. I use postgresql for the db. The app code is getting really messy(my begginer skills being a big factor) and slow, even when I run the app locally. </p>
  
  <p>This is an excerpt of my models.py file:</p>
  
  <pre><code>REPEATS_CHOICES = (
      (NEVER, 'Never'),
      (DAILY, 'Daily'),
      (WEEKLY, 'Weekly'),
      (MONTHLY, 'Monthly'),
      ...some more...
  )
  
  class Transaction(models.Model):
      name = models.CharField(max_length=30)
      type = models.IntegerField(max_length=1, choices=TYPE_CHOICES) # 0 = 'Income' , 1 = 'Expense'
      amount = models.DecimalField(max_digits=12, decimal_places=2)
      date = models.DateField(default=date.today)
      frequency = models.IntegerField(max_length=2, choices=REPEATS_CHOICES)
      ends = models.DateField(blank=True, null=True)
      active = models.BooleanField(default=True)
      category = models.ForeignKey(Category, related_name='transactions', blank=True, null=True)
      account = models.ForeignKey(Account, related_name='transactions')
  </code></pre>
  
  <p>The problem is with date, frequency and ends. With this info I can know all the dates in which transactions occurs and use it to fill a cashflow table. Doing things this way involves creating a lot of structures(dictionaries, lists and tuples) and iterating them a lot. Maybe there is a very simple way of solving this with the actual schema, but I couldn't realize how.</p>
  
  <p>I think that the app would be easier to code if, at the creation of a transaction, I could save all the dates in the db. I don't know if it's possible or if it's a good idea.</p>
  
  <p>I'm reading a book about google app engine and the datastore's multivalued properties. What do you think about this for solving my problem?.</p>
  
  <p>Edit: I didn't know about the PickleField. I'm now reading about it, maybe I could use it to store all the transaction's datetime objects.  </p>
  
  <p>Edit2: This is an excerpt of my cashflow2 view(sorry for the horrible code):</p>
  
  <pre><code>def cashflow2(request, account_name="Initial"):
  
  if account_name == "Initial":
      uri = "/cashflow/new_account"
      return HttpResponseRedirect(uri)     
  month_info = {}
  cat_info = {}
  m_y_list = [] # [(month,year),]
  trans = []
  min, max = [] , []
  
  account = Account.objects.get(name=account_name, user=request.user)
  categories = account.categories.all() 
  for year in range(2006,2017):
      for month in range(1,13):
          month_info[(month, year)] = [0, 0, 0]
          for cat in categories:
              cat_info[(cat, month, year)] = 0
  
  previous_months = 1 # previous months from actual
  next_months = 5
  dates_list = month_year_list(previous_month, next_months) # Returns [(month,year)] from the requested range
  m_y_list = [(date.month, date.year) for date in month_year_list(1,5)]
  min, max = dates_list[0], dates_list[-1]
  INCOME = 0
  EXPENSE = 1
  ONHAND = 2
  transacs_in_dates = []
  txs = account.transactions.order_by('date')
  
  for tx in txs:
      monthyear = ()
      monthyear = (tx.date.month, tx.date.year)
      if tx.frequency == 0:
          if tx.type == 0:
              month_info[monthyear][INCOME] += tx.amount
              if tx.category:
                  cat_info[(tx.category, monthyear[0], monthyear[1])] += tx.amount
          else:
              month_info[monthyear][EXPENSE] += tx.amount
              if tx.category:
                  cat_info[(tx.category, monthyear[0], monthyear[1])] += tx.amount
          if monthyear in lista_m_a:
              if tx not in transacs_in_dates:
                  transacs_in_dates.append(tx)
      elif tx.frequency == 4: # frequency = 'Monthly'
          months_dif = relativedelta.relativedelta(tx.ends, tx.date).months
          if tx.ends.day &lt; tx.date.day:
              months_dif += 1
          years_dif = relativedelta.relativedelta(tx.ends, tx.date).years
          dif = months_dif + (years_dif*12)
          dates_range = dif + 1
          for i in range(dates_range):
              dt = tx.date+relativedelta.relativedelta(months=+i)
              if (dt.month, dt.year) in m_y_list:
                  if tx not in transacs_in_dates:
                      transacs_in_dates.append(tx)
              if tx.type == 0:
                  month_info[(fch.month,fch.year)][INCOME] += tx.amount
                  if tx.category:
                      cat_info[(tx.category, fch.month, fch.year)] += tx.amount
              else:
                  month_info[(fch.month,fch.year)][EXPENSE] += tx.amount
                  if tx.category:
                      cat_info[(tx.category, fch.month, fch.year)] += tx.amount
  
  import operator
  thelist = []
  thelist = sorted((my + tuple(v) for my, v in month_info.iteritems()),
               key = operator.itemgetter(1, 0))
  thelistlist = []
  for atuple in thelist:
      thelistlist.append(list(atuple))
  for i in range(len(thelistlist)):
      if i != 0:
          thelistlist[i][4] = thelistlist[i-1][2] - thelistlist[i-1][3] + thelistlist[i-1][4]
  list = []
  for el in thelistlist:
      if (el[0],el[1]) in lista_m_a:
          list.append(el)
  
  transactions = account.transactions.all()
  
  cats_in_dates_income = []
  cats_in_dates_expense = []
  for t in transacs_in_dates:
      if t.category and t.type == 0:
          if t.category not in cats_in_dates_income:
              cats_in_dates_income.append(t.category)
      elif t.category and t.type == 1:
          if t.category not in cats_in_dates_expense:
              cats_in_dates_expense.append(t.category)
  
  cat_infos = []
  for k, v in cat_info.items():
      cat_infos.append((k[0], k[1], k[2], v))
  </code></pre>