├── coffee ├── coffee │ ├── __init__.py │ ├── wsgi.pyc │ ├── __init__.pyc │ ├── urls.py │ ├── wsgi.py │ └── settings.py ├── tracker │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0006_auto_20160322_1416.py │ │ ├── 0005_auto_20160322_1409.py │ │ ├── 0004_auto_20160322_1358.py │ │ ├── 0003_auto_20160322_1358.py │ │ ├── 0001_initial.py │ │ ├── 0008_auto_20160328_1732.py │ │ ├── 0007_auto_20160328_1720.py │ │ └── 0002_auto_20160322_1356.py │ ├── tests.py │ ├── admin.py │ ├── urls.py │ ├── views.py │ ├── apps.py │ └── models.py └── manage.py ├── .gitignore ├── v1-screenshot.png └── README.md /coffee/coffee/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /coffee/tracker/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /coffee/tracker/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.sqlite3 3 | 4 | -------------------------------------------------------------------------------- /coffee/tracker/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /v1-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/john-sandall/coffee-tracker/master/v1-screenshot.png -------------------------------------------------------------------------------- /coffee/coffee/wsgi.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/john-sandall/coffee-tracker/master/coffee/coffee/wsgi.pyc -------------------------------------------------------------------------------- /coffee/coffee/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/john-sandall/coffee-tracker/master/coffee/coffee/__init__.pyc -------------------------------------------------------------------------------- /coffee/tracker/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import Brew, Bean 4 | 5 | admin.site.register(Brew) 6 | admin.site.register(Bean) 7 | -------------------------------------------------------------------------------- /coffee/tracker/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | 3 | from . import views 4 | 5 | urlpatterns = [ 6 | url(r'^$', views.index, name='index'), 7 | ] 8 | -------------------------------------------------------------------------------- /coffee/tracker/views.py: -------------------------------------------------------------------------------- 1 | from django.http import HttpResponse 2 | 3 | 4 | def index(request): 5 | return HttpResponse("Hello, world. You're at the polls index.") 6 | -------------------------------------------------------------------------------- /coffee/tracker/apps.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.apps import AppConfig 4 | 5 | 6 | class TrackerConfig(AppConfig): 7 | name = 'tracker' 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Coffee Tracker 2 | Tiny Django app to help me track methods for making coffee + predictive models (eventually) to help make the perfect brew. 3 | 4 | ![Version 1](v1-screenshot.png "Version 1") 5 | -------------------------------------------------------------------------------- /coffee/coffee/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import include, url 2 | from django.contrib import admin 3 | 4 | urlpatterns = [ 5 | url(r'^tracker/', include('tracker.urls')), 6 | url(r'^admin/', admin.site.urls), 7 | ] 8 | -------------------------------------------------------------------------------- /coffee/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "coffee.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /coffee/coffee/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for coffee project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "coffee.settings") 12 | 13 | from django.core.wsgi import get_wsgi_application 14 | application = get_wsgi_application() 15 | -------------------------------------------------------------------------------- /coffee/tracker/migrations/0006_auto_20160322_1416.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.4 on 2016-03-22 14:16 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('tracker', '0005_auto_20160322_1409'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='brew', 17 | name='score', 18 | field=models.DecimalField(decimal_places=1, max_digits=2), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /coffee/tracker/migrations/0005_auto_20160322_1409.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.4 on 2016-03-22 14:09 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.utils.timezone 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('tracker', '0004_auto_20160322_1358'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AlterField( 17 | model_name='brew', 18 | name='brew_date', 19 | field=models.DateTimeField(default=django.utils.timezone.now), 20 | ), 21 | migrations.AlterField( 22 | model_name='brew', 23 | name='score', 24 | field=models.DecimalField(decimal_places=1, max_digits=1), 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /coffee/tracker/migrations/0004_auto_20160322_1358.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.4 on 2016-03-22 13:58 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.utils.timezone 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('tracker', '0003_auto_20160322_1358'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AlterField( 17 | model_name='brew', 18 | name='brew_date', 19 | field=models.DateField(default=django.utils.timezone.now), 20 | ), 21 | migrations.AlterField( 22 | model_name='brew', 23 | name='date_ground', 24 | field=models.DateField(default=django.utils.timezone.now), 25 | ), 26 | migrations.AlterField( 27 | model_name='brew', 28 | name='date_roasted', 29 | field=models.DateField(default=django.utils.timezone.now), 30 | ), 31 | ] 32 | -------------------------------------------------------------------------------- /coffee/tracker/migrations/0003_auto_20160322_1358.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.4 on 2016-03-22 13:58 3 | from __future__ import unicode_literals 4 | 5 | import datetime 6 | from django.db import migrations, models 7 | from django.utils.timezone import utc 8 | 9 | 10 | class Migration(migrations.Migration): 11 | 12 | dependencies = [ 13 | ('tracker', '0002_auto_20160322_1356'), 14 | ] 15 | 16 | operations = [ 17 | migrations.AlterField( 18 | model_name='brew', 19 | name='brew_date', 20 | field=models.DateField(default=datetime.datetime(2016, 3, 22, 13, 58, 0, 199892, tzinfo=utc)), 21 | ), 22 | migrations.AlterField( 23 | model_name='brew', 24 | name='date_ground', 25 | field=models.DateField(default=datetime.datetime(2016, 3, 22, 13, 58, 0, 200456, tzinfo=utc)), 26 | ), 27 | migrations.AlterField( 28 | model_name='brew', 29 | name='date_roasted', 30 | field=models.DateField(default=datetime.datetime(2016, 3, 22, 13, 58, 0, 200411, tzinfo=utc)), 31 | ), 32 | ] 33 | -------------------------------------------------------------------------------- /coffee/tracker/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.4 on 2016-03-22 13:22 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.db.models.deletion 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | initial = True 12 | 13 | dependencies = [ 14 | ] 15 | 16 | operations = [ 17 | migrations.CreateModel( 18 | name='Choice', 19 | fields=[ 20 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 21 | ('choice_text', models.CharField(max_length=200)), 22 | ('votes', models.IntegerField(default=0)), 23 | ], 24 | ), 25 | migrations.CreateModel( 26 | name='Question', 27 | fields=[ 28 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 29 | ('question_text', models.CharField(max_length=200)), 30 | ('pub_date', models.DateTimeField(verbose_name=b'date published')), 31 | ], 32 | ), 33 | migrations.AddField( 34 | model_name='choice', 35 | name='question', 36 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tracker.Question'), 37 | ), 38 | ] 39 | -------------------------------------------------------------------------------- /coffee/coffee/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for coffee project. 3 | 4 | For more information on this file, see 5 | https://docs.djangoproject.com/en/1.7/topics/settings/ 6 | 7 | For the full list of settings and their values, see 8 | https://docs.djangoproject.com/en/1.7/ref/settings/ 9 | """ 10 | 11 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 12 | import os 13 | BASE_DIR = os.path.dirname(os.path.dirname(__file__)) 14 | 15 | 16 | # Quick-start development settings - unsuitable for production 17 | # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ 18 | 19 | # SECURITY WARNING: keep the secret key used in production secret! 20 | SECRET_KEY = '_5$p^dkz&#*-cw34z*9gp=shl!mg3dq%99i%27xx%+%d%7+$e5' 21 | 22 | # SECURITY WARNING: don't run with debug turned on in production! 23 | DEBUG = True 24 | 25 | TEMPLATE_DEBUG = True 26 | 27 | ALLOWED_HOSTS = [] 28 | 29 | 30 | # Application definition 31 | 32 | INSTALLED_APPS = ( 33 | 'tracker.apps.TrackerConfig', 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | ) 41 | 42 | MIDDLEWARE_CLASSES = ( 43 | 'django.contrib.sessions.middleware.SessionMiddleware', 44 | 'django.middleware.common.CommonMiddleware', 45 | 'django.middleware.csrf.CsrfViewMiddleware', 46 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 47 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 48 | 'django.contrib.messages.middleware.MessageMiddleware', 49 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 50 | ) 51 | 52 | ROOT_URLCONF = 'coffee.urls' 53 | 54 | WSGI_APPLICATION = 'coffee.wsgi.application' 55 | 56 | 57 | # Database 58 | # https://docs.djangoproject.com/en/1.7/ref/settings/#databases 59 | 60 | DATABASES = { 61 | 'default': { 62 | 'ENGINE': 'django.db.backends.sqlite3', 63 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 64 | } 65 | } 66 | 67 | # Internationalization 68 | # https://docs.djangoproject.com/en/1.7/topics/i18n/ 69 | 70 | LANGUAGE_CODE = 'en-us' 71 | 72 | TIME_ZONE = 'UTC' 73 | 74 | USE_I18N = True 75 | 76 | USE_L10N = True 77 | 78 | USE_TZ = True 79 | 80 | 81 | # Static files (CSS, JavaScript, Images) 82 | # https://docs.djangoproject.com/en/1.7/howto/static-files/ 83 | 84 | STATIC_URL = '/static/' 85 | -------------------------------------------------------------------------------- /coffee/tracker/migrations/0008_auto_20160328_1732.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.4 on 2016-03-28 17:32 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('tracker', '0007_auto_20160328_1720'), 12 | ] 13 | 14 | operations = [ 15 | migrations.RemoveField( 16 | model_name='brew', 17 | name='altitude', 18 | ), 19 | migrations.RemoveField( 20 | model_name='brew', 21 | name='country', 22 | ), 23 | migrations.RemoveField( 24 | model_name='brew', 25 | name='date_ground', 26 | ), 27 | migrations.RemoveField( 28 | model_name='brew', 29 | name='date_roasted', 30 | ), 31 | migrations.RemoveField( 32 | model_name='brew', 33 | name='farmer_answer', 34 | ), 35 | migrations.RemoveField( 36 | model_name='brew', 37 | name='farmer_question', 38 | ), 39 | migrations.RemoveField( 40 | model_name='brew', 41 | name='grind', 42 | ), 43 | migrations.RemoveField( 44 | model_name='brew', 45 | name='ground_by', 46 | ), 47 | migrations.RemoveField( 48 | model_name='brew', 49 | name='hints_of', 50 | ), 51 | migrations.RemoveField( 52 | model_name='brew', 53 | name='name', 54 | ), 55 | migrations.RemoveField( 56 | model_name='brew', 57 | name='origin', 58 | ), 59 | migrations.RemoveField( 60 | model_name='brew', 61 | name='pact_reviewer_name', 62 | ), 63 | migrations.RemoveField( 64 | model_name='brew', 65 | name='pact_reviewer_says', 66 | ), 67 | migrations.RemoveField( 68 | model_name='brew', 69 | name='process', 70 | ), 71 | migrations.RemoveField( 72 | model_name='brew', 73 | name='producer', 74 | ), 75 | migrations.RemoveField( 76 | model_name='brew', 77 | name='roast_type', 78 | ), 79 | migrations.RemoveField( 80 | model_name='brew', 81 | name='tasting_notes_acidity', 82 | ), 83 | migrations.RemoveField( 84 | model_name='brew', 85 | name='tasting_notes_flavour', 86 | ), 87 | migrations.RemoveField( 88 | model_name='brew', 89 | name='tasting_notes_mouthfeel', 90 | ), 91 | migrations.RemoveField( 92 | model_name='brew', 93 | name='tasting_notes_sweetness', 94 | ), 95 | migrations.RemoveField( 96 | model_name='brew', 97 | name='varietal', 98 | ), 99 | migrations.RemoveField( 100 | model_name='brew', 101 | name='vendor', 102 | ), 103 | ] 104 | -------------------------------------------------------------------------------- /coffee/tracker/migrations/0007_auto_20160328_1720.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | import django.utils.timezone 6 | import datetime 7 | from django.utils.timezone import utc 8 | 9 | 10 | class Migration(migrations.Migration): 11 | 12 | dependencies = [ 13 | ('tracker', '0006_auto_20160322_1416'), 14 | ] 15 | 16 | operations = [ 17 | migrations.CreateModel( 18 | name='Bean', 19 | fields=[ 20 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 21 | ('vendor', models.CharField(max_length=200)), 22 | ('name', models.CharField(max_length=200)), 23 | ('grind', models.CharField(max_length=200)), 24 | ('country', models.CharField(max_length=200)), 25 | ('date_roasted', models.DateField(default=django.utils.timezone.now)), 26 | ('date_ground', models.DateField(default=django.utils.timezone.now)), 27 | ('ground_by', models.CharField(max_length=200)), 28 | ('hints_of', models.CharField(max_length=200)), 29 | ('roast_type', models.CharField(max_length=200)), 30 | ('producer', models.CharField(max_length=200)), 31 | ('process', models.CharField(max_length=200)), 32 | ('origin', models.CharField(max_length=200)), 33 | ('varietal', models.CharField(max_length=200)), 34 | ('altitude', models.CharField(max_length=200)), 35 | ('farmer_question', models.TextField()), 36 | ('farmer_answer', models.TextField()), 37 | ('tasting_notes_flavour', models.CharField(max_length=200)), 38 | ('tasting_notes_sweetness', models.CharField(max_length=200)), 39 | ('tasting_notes_acidity', models.CharField(max_length=200)), 40 | ('tasting_notes_mouthfeel', models.CharField(max_length=200)), 41 | ('pact_reviewer_name', models.CharField(max_length=200)), 42 | ('pact_reviewer_says', models.TextField()), 43 | ], 44 | options={ 45 | }, 46 | bases=(models.Model,), 47 | ), 48 | migrations.RemoveField( 49 | model_name='brew', 50 | name='kettle_boiled', 51 | ), 52 | migrations.AddField( 53 | model_name='brew', 54 | name='bean', 55 | field=models.ForeignKey(default=1, to='tracker.Bean'), 56 | preserve_default=False, 57 | ), 58 | migrations.AlterField( 59 | model_name='brew', 60 | name='hot_water_added', 61 | field=models.BooleanField(default=False), 62 | preserve_default=True, 63 | ), 64 | migrations.AlterField( 65 | model_name='brew', 66 | name='milk_added', 67 | field=models.BooleanField(default=False), 68 | preserve_default=True, 69 | ), 70 | migrations.AlterField( 71 | model_name='brew', 72 | name='repour_into_mug', 73 | field=models.BooleanField(default=False), 74 | preserve_default=True, 75 | ), 76 | migrations.AlterField( 77 | model_name='brew', 78 | name='sugar_added', 79 | field=models.BooleanField(default=False), 80 | preserve_default=True, 81 | ), 82 | ] 83 | -------------------------------------------------------------------------------- /coffee/tracker/migrations/0002_auto_20160322_1356.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.4 on 2016-03-22 13:56 3 | from __future__ import unicode_literals 4 | 5 | import datetime 6 | from django.db import migrations, models 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('tracker', '0001_initial'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='Brew', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('brew_date', models.DateField(default=datetime.date(2016, 3, 22))), 21 | ('vendor', models.CharField(max_length=200)), 22 | ('name', models.CharField(max_length=200)), 23 | ('grind', models.CharField(max_length=200)), 24 | ('country', models.CharField(max_length=200)), 25 | ('date_roasted', models.DateField(default=datetime.date(2016, 3, 22))), 26 | ('date_ground', models.DateField(default=datetime.date(2016, 3, 22))), 27 | ('ground_by', models.CharField(max_length=200)), 28 | ('hints_of', models.CharField(max_length=200)), 29 | ('roast_type', models.CharField(max_length=200)), 30 | ('producer', models.CharField(max_length=200)), 31 | ('process', models.CharField(max_length=200)), 32 | ('origin', models.CharField(max_length=200)), 33 | ('varietal', models.CharField(max_length=200)), 34 | ('altitude', models.CharField(max_length=200)), 35 | ('farmer_question', models.TextField()), 36 | ('farmer_answer', models.TextField()), 37 | ('tasting_notes_flavour', models.CharField(max_length=200)), 38 | ('tasting_notes_sweetness', models.CharField(max_length=200)), 39 | ('tasting_notes_acidity', models.CharField(max_length=200)), 40 | ('tasting_notes_mouthfeel', models.CharField(max_length=200)), 41 | ('pact_reviewer_name', models.CharField(max_length=200)), 42 | ('pact_reviewer_says', models.TextField()), 43 | ('kettle_boiled', models.BooleanField()), 44 | ('water_type', models.CharField(max_length=200)), 45 | ('kettle_cooldown_time', models.IntegerField(default=0)), 46 | ('water_temperature', models.IntegerField(default=0)), 47 | ('brew_method', models.CharField(max_length=200)), 48 | ('brew_submethod', models.CharField(max_length=200)), 49 | ('inspired_by', models.CharField(max_length=200)), 50 | ('coffee_amount', models.CharField(max_length=200)), 51 | ('initial_water_volume', models.CharField(max_length=200)), 52 | ('stir_amount', models.CharField(max_length=200)), 53 | ('bloom_time', models.CharField(max_length=200)), 54 | ('second_water_volume', models.CharField(max_length=200)), 55 | ('second_water_time', models.CharField(max_length=200)), 56 | ('plunge_time', models.CharField(max_length=200)), 57 | ('plunge_into', models.CharField(max_length=200)), 58 | ('repour_into_mug', models.BooleanField()), 59 | ('hot_water_added', models.BooleanField()), 60 | ('milk_added', models.BooleanField()), 61 | ('sugar_added', models.BooleanField()), 62 | ('score', models.IntegerField(default=0)), 63 | ('comments', models.TextField()), 64 | ], 65 | ), 66 | migrations.RemoveField( 67 | model_name='choice', 68 | name='question', 69 | ), 70 | migrations.DeleteModel( 71 | name='Choice', 72 | ), 73 | migrations.DeleteModel( 74 | name='Question', 75 | ), 76 | ] 77 | -------------------------------------------------------------------------------- /coffee/tracker/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.utils import timezone 3 | from django.utils.encoding import python_2_unicode_compatible 4 | 5 | 6 | # From http://stackoverflow.com/questions/5891555/display-the-date-like-may-5th-using-pythons-strftime 7 | def suffix(d): 8 | return 'th' if 11 <= d <= 13 else {1: 'st', 2: 'nd', 3: 'rd'}.get(d % 10, 'th') 9 | 10 | 11 | def custom_strftime(format, t): 12 | return t.strftime(format).replace('{S}', str(t.day) + suffix(t.day)) 13 | 14 | 15 | @python_2_unicode_compatible # only if you need to support Python 2 16 | class Brew(models.Model): 17 | def __str__(self): 18 | return "{0} ({1})".format(self.bean.vendor, custom_strftime('%a {S} %B', self.brew_date)) 19 | 20 | # Timescales 21 | brew_date = models.DateTimeField(default=timezone.now) 22 | 23 | # Beans 24 | bean = models.ForeignKey('Bean', on_delete=models.CASCADE) 25 | 26 | # Water 27 | water_type = models.CharField(max_length=200) # e.g. tap water 28 | kettle_cooldown_time = models.IntegerField(default=0) 29 | water_temperature = models.IntegerField(default=0) 30 | 31 | # Brew method 32 | brew_method = models.CharField(max_length=200) # e.g. Aeropress 33 | brew_submethod = models.CharField(max_length=200) # e.g. Standard/Inverted 34 | inspired_by = models.CharField(max_length=200) 35 | coffee_amount = models.CharField(max_length=200) # e.g. 1 level scoop 36 | initial_water_volume = models.CharField(max_length=200) # e.g. up to #1 37 | stir_amount = models.CharField(max_length=200) # e.g. 5 times 38 | bloom_time = models.CharField(max_length=200) # e.g. 25 seconds 39 | second_water_volume = models.CharField(max_length=200) # e.g. up to #3 40 | second_water_time = models.CharField(max_length=200) # e.g. 20 seconds 41 | plunge_time = models.CharField(max_length=200) # e.g. 60 seconds 42 | plunge_into = models.CharField(max_length=200) # e.g. cold cup 43 | repour_into_mug = models.BooleanField(default=False) 44 | hot_water_added = models.BooleanField(default=False) 45 | milk_added = models.BooleanField(default=False) 46 | sugar_added = models.BooleanField(default=False) 47 | 48 | # My tasting notes 49 | score = models.DecimalField(max_digits=2, decimal_places=1) # e.g. 3.5 is "good to great" 50 | comments = models.TextField() 51 | 52 | 53 | @python_2_unicode_compatible # only if you need to support Python 2 54 | class Bean(models.Model): 55 | def __str__(self): 56 | return "{0}, {1} ({2})".format(self.name, self.vendor, custom_strftime('%a {S} %B', self.date_roasted)) 57 | 58 | # Beans 59 | vendor = models.CharField(max_length=200) # e.g. Pact 60 | name = models.CharField(max_length=200) # e.g. Sertaeo Pulped Natural 61 | grind = models.CharField(max_length=200) # e.g. aeropress 62 | country = models.CharField(max_length=200) # e.g. Brazil 63 | date_roasted = models.DateField(default=timezone.now) 64 | date_ground = models.DateField(default=timezone.now) 65 | ground_by = models.CharField(max_length=200) # e.g. Eleni 66 | hints_of = models.CharField(max_length=200) # e.g. Hazeulnut & Milk Chocolate 67 | roast_type = models.CharField(max_length=200) # e.g. Medium Roast 68 | producer = models.CharField(max_length=200) 69 | process = models.CharField(max_length=200) 70 | origin = models.CharField(max_length=200) 71 | varietal = models.CharField(max_length=200) 72 | altitude = models.CharField(max_length=200) 73 | farmer_question = models.TextField() 74 | farmer_answer = models.TextField() 75 | 76 | # Vendor's tasting notes 77 | tasting_notes_flavour = models.CharField(max_length=200) 78 | tasting_notes_sweetness = models.CharField(max_length=200) 79 | tasting_notes_acidity = models.CharField(max_length=200) 80 | tasting_notes_mouthfeel = models.CharField(max_length=200) 81 | pact_reviewer_name = models.CharField(max_length=200) 82 | pact_reviewer_says = models.TextField() 83 | 84 | 85 | # @python_2_unicode_compatible # only if you need to support Python 2 86 | # class Choice(models.Model): 87 | # def __str__(self): 88 | # return self.choice_text 89 | # question = models.ForeignKey(Question, on_delete=models.CASCADE) 90 | # choice_text = models.CharField(max_length=200) 91 | # votes = models.IntegerField(default=0) 92 | --------------------------------------------------------------------------------