Rename yeast batch to propogation.

Refrences to yeast `batches` are now `propogations`.

Hopefully less confusing now...
Closes #6
This commit is contained in:
Chris Giacofei 2024-06-07 11:27:41 -04:00
parent f396dacee5
commit 3468c38008
8 changed files with 78 additions and 46 deletions

View File

@ -2,15 +2,15 @@ from django.contrib import admin
from django.urls import reverse from django.urls import reverse
from django.utils.html import format_html from django.utils.html import format_html
from django.apps import apps from django.apps import apps
from yeast.models import Yeast, Strain, Manufacturer, Storage, Batch from yeast.models import Yeast, Strain, Manufacturer, Storage, Propogation
from yeast.forms import YeastModelForm from yeast.forms import YeastModelForm
import beer import beer
from config.extras import BREWFATHER_APP_ROOT from config.extras import BREWFATHER_APP_ROOT
class BatchInline(admin.TabularInline): class PropogationInline(admin.TabularInline):
model = Batch model = Propogation
extra = 0 extra = 0
class SampleInline(admin.TabularInline): class SampleInline(admin.TabularInline):
@ -23,11 +23,11 @@ class StrainInline(admin.TabularInline):
class ParentInline(admin.TabularInline): class ParentInline(admin.TabularInline):
verbose_name = 'Parent Samples' verbose_name = 'Parent Samples'
model = Batch.parent.through model = Propogation.parent.through
@admin.register(Yeast) @admin.register(Yeast)
class YeastAdmin(admin.ModelAdmin): class YeastAdmin(admin.ModelAdmin):
list_display = [ 'batch', 'url', 'lot_number', 'age', 'storage', 'viability', 'generation_num', 'cellcount', 'pitched', 'date_pitched', 'pitched_batch'] list_display = [ 'propogation', 'url', 'lot_number', 'age', 'storage', 'viability', 'generation_num', 'cellcount', 'pitched', 'date_pitched', 'pitched_batch']
list_editable = ['pitched', 'date_pitched', 'pitched_batch', 'lot_number'] list_editable = ['pitched', 'date_pitched', 'pitched_batch', 'lot_number']
def batch_url(self, obj): def batch_url(self, obj):
@ -43,7 +43,7 @@ class YeastAdmin(admin.ModelAdmin):
class StrainAdmin(admin.ModelAdmin): class StrainAdmin(admin.ModelAdmin):
list_display = ['name', 'long_name', 'manufacturer', 'avilable_batches'] list_display = ['name', 'long_name', 'manufacturer', 'avilable_batches']
inlines = [ inlines = [
BatchInline, PropogationInline,
] ]
list_editable = ['long_name', 'manufacturer'] list_editable = ['long_name', 'manufacturer']
@ -58,7 +58,7 @@ class StrainAdmin(admin.ModelAdmin):
urls.append('<a href="{}">{}</a>'.format(url, url_text)) urls.append('<a href="{}">{}</a>'.format(url, url_text))
return format_html(', '.join(urls)) return format_html(', '.join(urls))
avilable_batches.short_description = 'Available Batches' avilable_batches.short_description = 'Available Propogation'
@admin.register(Storage) @admin.register(Storage)
class StorageAdmin(admin.ModelAdmin): class StorageAdmin(admin.ModelAdmin):
@ -78,8 +78,8 @@ class ManufacturerAdmin(admin.ModelAdmin):
if obj.website: if obj.website:
return format_html("<a href='{url}'>{url}</a>", url=obj.website) return format_html("<a href='{url}'>{url}</a>", url=obj.website)
@admin.register(Batch) @admin.register(Propogation)
class BatchAdmin(admin.ModelAdmin): class PropogationAdmin(admin.ModelAdmin):
list_display = ['strain', 'consumed', 'source', 'parent_samples', 'production_date', 'avilable_samples', 'used_samples'] list_display = ['strain', 'consumed', 'source', 'parent_samples', 'production_date', 'avilable_samples', 'used_samples']
form = YeastModelForm form = YeastModelForm
filter_horizontal = ['parent'] filter_horizontal = ['parent']
@ -89,7 +89,7 @@ class BatchAdmin(admin.ModelAdmin):
] ]
def save_related(self, request, form, formsets, change): def save_related(self, request, form, formsets, change):
super(BatchAdmin, self).save_related(request, form, formsets, change) super(PropogationAdmin, self).save_related(request, form, formsets, change)
if form.instance.source_batch: if form.instance.source_batch:
relate_samples = [x for x in Yeast.objects.all() if x.pitched_batch==form.instance.source_batch] relate_samples = [x for x in Yeast.objects.all() if x.pitched_batch==form.instance.source_batch]
for sample in relate_samples: for sample in relate_samples:

View File

@ -1,7 +1,7 @@
from django import forms from django import forms
from django.urls import reverse from django.urls import reverse
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from .models import Yeast, Batch, Strain from .models import Yeast, Propogation, Strain
import logging import logging
logger = logging.getLogger('django') logger = logging.getLogger('django')
@ -30,7 +30,7 @@ class BatchAddForm(forms.ModelForm):
# create meta class # create meta class
class Meta: class Meta:
# specify model to be used # specify model to be used
model = Batch model = Propogation
# specify fields to be used # specify fields to be used
fields = [ fields = [

View File

@ -0,0 +1,22 @@
# Generated by Django 5.0.6 on 2024-06-07 15:16
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('yeast', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='batch',
options={'verbose_name': 'Propagation', 'verbose_name_plural': 'Propagations'},
),
migrations.RenameField(
model_name='yeast',
old_name='batch',
new_name='propogation',
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 5.0.6 on 2024-06-07 15:21
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('beer', '0001_initial'),
('yeast', '0002_alter_batch_options_rename_batch_yeast_propogation'),
]
operations = [
migrations.RenameModel(
old_name='Batch',
new_name='Propogation',
),
]

View File

@ -48,7 +48,7 @@ class Strain(CustomModel):
@property @property
def batches_available(self): def batches_available(self):
return [x for x in Batch.objects.all() if not x.consumed and x.strain==self] return [x for x in Propogation.objects.all() if not x.consumed and x.strain==self]
def __str__(self): def __str__(self):
# Return a string that represents the instance # Return a string that represents the instance
@ -68,13 +68,14 @@ class Storage(CustomModel):
return self.name return self.name
class Batch(CustomModel): class Propogation(CustomModel):
""" """
Stores a batch of :model:`yeast.Yeast` of a single :model:`yeast.Strain`. Stores a batch of :model:`yeast.Yeast` of a single :model:`yeast.Strain`.
Can be a single purchased pack, or multiple vials Can be a single purchased pack, or multiple vials
to be frozen from a starter. to be frozen from a starter.
""" """
BATCH_TYPES = { BATCH_TYPES = {
'ST': 'Store', 'ST': 'Store',
'PR': 'Propogated', 'PR': 'Propogated',
@ -89,7 +90,7 @@ class Batch(CustomModel):
notes = models.TextField(max_length=500, blank=True, null=True) notes = models.TextField(max_length=500, blank=True, null=True)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
super(Batch, self).save(*args, **kwargs) super(Propogation, self).save(*args, **kwargs)
if self.source_batch: if self.source_batch:
relate_samples = [x for x in Yeast.objects.all() if x.pitched_batch==self.source_batch] relate_samples = [x for x in Yeast.objects.all() if x.pitched_batch==self.source_batch]
for sample in relate_samples: for sample in relate_samples:
@ -97,19 +98,19 @@ class Batch(CustomModel):
@property @property
def age(self): def age(self):
return int(average([x.age for x in Yeast.available.all() if x.batch == self])) return int(average([x.age for x in Yeast.available.all() if x.propogation == self]))
@property @property
def max_viability(self): def max_viability(self):
return int(max([x.viability for x in Yeast.available.all() if x.batch == self]) * 100) return int(max([x.viability for x in Yeast.available.all() if x.propogation == self]) * 100)
@property @property
def min_viability(self): def min_viability(self):
return int(min([x.viability for x in Yeast.available.all() if x.batch == self]) * 100) return int(min([x.viability for x in Yeast.available.all() if x.propogation == self]) * 100)
@property @property
def generation(self): def generation(self):
return int(average([x.generation_num for x in Yeast.available.all() if x.batch == self])) return int(average([x.generation_num for x in Yeast.available.all() if x.propogation == self]))
@property @property
def beer_name(self): def beer_name(self):
@ -132,11 +133,11 @@ class Batch(CustomModel):
@property @property
def remaining_samples(self): def remaining_samples(self):
return [x for x in Yeast.available.all() if x.batch==self] return [x for x in Yeast.available.all() if x.propogation==self]
@property @property
def used_samples(self): def used_samples(self):
return [x for x in Yeast.objects.all() if x.batch==self and x.pitched] return [x for x in Yeast.objects.all() if x.propogation==self and x.pitched]
def __str__(self): def __str__(self):
# Return a string that represents the instance # Return a string that represents the instance
@ -148,7 +149,7 @@ class Yeast(CustomModel):
Store an individual sample of yeast. Store an individual sample of yeast.
""" """
id = DateUUIDField(primary_key=True) id = DateUUIDField(primary_key=True)
batch = models.ForeignKey(Batch, on_delete=models.CASCADE) propogation = models.ForeignKey(Propogation, on_delete=models.CASCADE)
generation_num = models.IntegerField(default=0) generation_num = models.IntegerField(default=0)
storage = models.ForeignKey(Storage, on_delete=models.CASCADE) storage = models.ForeignKey(Storage, on_delete=models.CASCADE)
cellcount = models.IntegerField(default=100) cellcount = models.IntegerField(default=100)
@ -163,7 +164,7 @@ class Yeast(CustomModel):
@property @property
def name(self): def name(self):
return '{} {}'.format(self.id, self.batch.strain.name) return '{} {}'.format(self.id, self.propogation.strain.name)
@property @property
def age(self): def age(self):
@ -174,7 +175,7 @@ class Yeast(CustomModel):
else: else:
end_date = timezone.now().date() end_date = timezone.now().date()
return abs((self.batch.production_date-end_date).days) return abs((self.propogation.production_date-end_date).days)
@property @property
def viability(self): def viability(self):
@ -183,13 +184,4 @@ class Yeast(CustomModel):
def __str__(self): def __str__(self):
# Return a string that represents the instance # Return a string that represents the instance
return '{} {}'.format(self.id, self.batch.strain.name) return '{} {}'.format(self.id, self.propogation.strain.name)
# class BeerBatch(CustomModel):
# brewfather_id = models.CharField(max_length=50)
# brewfather_num = models.IntegerField(default=1)
# brewfather_name = models.CharField(max_length=500, default='name')
# def __str__(self):
# # Return a string that represents the instance
# return 'BF #{num}: {name}'.format(name=self.brewfather_name, num=self.brewfather_num)

View File

@ -49,7 +49,7 @@
</fieldset> </fieldset>
</div> </div>
<div class="col-md-6 form-group"> <div class="col-md-6 form-group">
<legend>Print Selected Labels for this Batch</legend> <legend>Print Selected Labels for this Propogation</legend>
<p><p> <p><p>
<label for="skip_count">Number of labels already removed from the sheet: </label> <label for="skip_count">Number of labels already removed from the sheet: </label>
<input id="skip_count" type="number" name="skip_count" value=0 size="4"> <input id="skip_count" type="number" name="skip_count" value=0 size="4">

View File

@ -16,7 +16,7 @@ input, label {
<div class="container" id="main"> <div class="container" id="main">
<h3>Batches</h3> <h3>Yeast Propogations</h3>
<form action="{% url 'yeast:get_batch' %}" method="post"> <form action="{% url 'yeast:get_batch' %}" method="post">
{% csrf_token %} {% csrf_token %}
@ -37,7 +37,7 @@ input, label {
<div class="container m-2"> <div class="container m-2">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
<label for="batch-select">Choose a batch:</label> <label for="batch-select">Choose a propogation:</label>
<select name="batch" id="batch-select" size="10" style="min-width:100%;"> <select name="batch" id="batch-select" size="10" style="min-width:100%;">
{% for batch in batches %} {% for batch in batches %}
{% if not batch.consumed %} {% if not batch.consumed %}
@ -56,7 +56,7 @@ input, label {
{% if batch.source == 'SL' %} {% if batch.source == 'SL' %}
<th>Yeast Source</th><td>{{ batch.get_source_display }} <a href="{{ batch.beer_url }}">#{{ batch.beer_num }} {{ batch.beer_name }}</a></td> <th>Yeast Source</th><td>{{ batch.get_source_display }} <a href="{{ batch.beer_url }}">#{{ batch.beer_num }} {{ batch.beer_name }}</a></td>
{% elif batch.source == 'ST' %} {% elif batch.source == 'ST' %}
<th>Batch Source</th><td>Purchased from Store</td> <th>Yeast Source</th><td>Purchased from Store</td>
{% endif %} {% endif %}
</tr> </tr>
<tr> <tr>
@ -86,7 +86,7 @@ input, label {
</div> </div>
</div> </div>
<div class="container m-2"> <div class="container m-2">
<input type="submit" value="Go to Batch Page"> <input type="submit" value="Go to Yeast Propogation Page">
</div> </div>
</div> </div>

View File

@ -6,7 +6,7 @@ from django.urls import reverse
from django.http import JsonResponse from django.http import JsonResponse
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from yeast.models import Yeast, Batch, Strain from yeast.models import Yeast, Propogation, Strain
from config.extras import AveryLabel from config.extras import AveryLabel
from yeast.forms import BatchAddForm, StrainAddForm from yeast.forms import BatchAddForm, StrainAddForm
@ -18,12 +18,12 @@ class YeastListView(ListView):
model = Yeast model = Yeast
class BatchListView(ListView): class BatchListView(ListView):
model = Batch model = Propogation
def sample(request, yeast_id): def sample(request, yeast_id):
sample = get_object_or_404(Yeast, pk=yeast_id) sample = get_object_or_404(Yeast, pk=yeast_id)
sample_batch = get_object_or_404(Batch, pk=sample.batch_id) sample_batch = get_object_or_404(Propogation, pk=sample.batch_id)
return render(request, 'yeast/sample.html', {'sample': sample, 'batch':sample_batch}) return render(request, 'yeast/sample.html', {'sample': sample, 'batch':sample_batch})
# @login_required # @login_required
@ -43,7 +43,7 @@ def get_batch(request):
return redirect(re_url) return redirect(re_url)
def home(request): def home(request):
return render(request, 'yeast/home.html',{'batches': Batch.objects.all, 'strains': Strain.objects.all}) return render(request, 'yeast/home.html',{'batches': Propogation.objects.all, 'strains': Strain.objects.all})
def batch(request, batch_id): def batch(request, batch_id):
""" """
@ -55,7 +55,7 @@ def batch(request, batch_id):
``Template`` ``Template``
:template:`yeast/batch.html` :template:`yeast/batch.html`
""" """
batch = get_object_or_404(Batch, pk=batch_id) batch = get_object_or_404(Propogation, pk=batch_id)
return render(request, 'yeast/batch.html', {'batch': batch}) return render(request, 'yeast/batch.html', {'batch': batch})
def batch_labels(request, batch_id): def batch_labels(request, batch_id):
@ -69,7 +69,7 @@ def batch_labels(request, batch_id):
""" """
skip_count = request.POST.get("skip_count", "") skip_count = request.POST.get("skip_count", "")
samples = request.POST.getlist("samples", "") samples = request.POST.getlist("samples", "")
batch = get_object_or_404(Batch, pk=batch_id) batch = get_object_or_404(Propogation, pk=batch_id)
to_print = list(filter(lambda d: str(d.id) in samples, batch.yeast_set.all())) to_print = list(filter(lambda d: str(d.id) in samples, batch.yeast_set.all()))
# Create the HttpResponse object with the appropriate PDF headers. # Create the HttpResponse object with the appropriate PDF headers.
@ -96,7 +96,7 @@ def batch_labels(request, batch_id):
return response return response
class addBatch(CreateView): class addBatch(CreateView):
model = Batch model = Propogation
form_class = BatchAddForm form_class = BatchAddForm
def get_success_url(self): def get_success_url(self):