Compare commits
7 Commits
f396dacee5
...
1e8d79b7cf
Author | SHA1 | Date | |
---|---|---|---|
1e8d79b7cf | |||
8c5896b6b1 | |||
3468c38008 | |||
651cfe9162 | |||
74e8a3135a | |||
a6c244756e | |||
c3634141a3 |
@ -1,6 +1,8 @@
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
from config.extras import BREWFATHER_APP_ROOT
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger('django')
|
||||
|
||||
@ -18,6 +20,10 @@ class Batch(CustomModel):
|
||||
brewfather_name = models.CharField(max_length=500, default='name')
|
||||
recipe = models.ForeignKey('BatchRecipe', on_delete=models.CASCADE, default=1)
|
||||
|
||||
@property
|
||||
def brewfather_url(self):
|
||||
return '{}/tabs/batches/batch/{}'.format(BREWFATHER_APP_ROOT, self.brewfather_id)
|
||||
|
||||
def __str__(self):
|
||||
# Return a string that represents the instance
|
||||
return 'BF #{num}: {name}'.format(name=self.brewfather_name, num=self.brewfather_num)
|
||||
|
@ -39,8 +39,8 @@ class MaintenanceAdmin(admin.ModelAdmin):
|
||||
class EquipmentAdmin(admin.ModelAdmin):
|
||||
|
||||
readonly_fields = ('id',)
|
||||
list_display = ['id', 'state', 'equipment_type', 'keg_type', 'state']
|
||||
list_editable = ['state', 'equipment_type', 'keg_type', 'state']
|
||||
list_display = ['id', 'equipment_type', 'keg_type', 'state']
|
||||
list_editable = ['state', 'state']
|
||||
|
||||
@admin.register(KegType)
|
||||
class KegTypeAdmin(admin.ModelAdmin):
|
||||
|
@ -8,12 +8,12 @@
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
|
||||
<!-- JS, Popper.js, and jQuery -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"
|
||||
integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
|
||||
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
|
||||
crossorigin="anonymous"></script>
|
||||
<!-- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" -->
|
||||
<!-- integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" -->
|
||||
<!-- crossorigin="anonymous"></script> -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
||||
{% block script %}{% endblock %}
|
||||
<style>
|
||||
{% block style %}{% endblock %}
|
||||
@ -23,6 +23,15 @@
|
||||
label {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.table-borderless > tbody > tr > td,
|
||||
.table-borderless > tbody > tr > th,
|
||||
.table-borderless > tfoot > tr > td,
|
||||
.table-borderless > tfoot > tr > th,
|
||||
.table-borderless > thead > tr > td,
|
||||
.table-borderless > thead > tr > th {
|
||||
border: none;
|
||||
background-color: rgba(0,0,0, 0.0) !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -90,8 +99,6 @@
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
||||
|
||||
</body>
|
||||
{% block endscript %}{% endblock %}
|
||||
</html>
|
||||
|
@ -2,15 +2,15 @@ from django.contrib import admin
|
||||
from django.urls import reverse
|
||||
from django.utils.html import format_html
|
||||
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
|
||||
|
||||
import beer
|
||||
|
||||
from config.extras import BREWFATHER_APP_ROOT
|
||||
|
||||
class BatchInline(admin.TabularInline):
|
||||
model = Batch
|
||||
class PropogationInline(admin.TabularInline):
|
||||
model = Propogation
|
||||
extra = 0
|
||||
|
||||
class SampleInline(admin.TabularInline):
|
||||
@ -23,11 +23,11 @@ class StrainInline(admin.TabularInline):
|
||||
|
||||
class ParentInline(admin.TabularInline):
|
||||
verbose_name = 'Parent Samples'
|
||||
model = Batch.parent.through
|
||||
model = Propogation.parent.through
|
||||
|
||||
@admin.register(Yeast)
|
||||
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']
|
||||
|
||||
def batch_url(self, obj):
|
||||
@ -43,7 +43,7 @@ class YeastAdmin(admin.ModelAdmin):
|
||||
class StrainAdmin(admin.ModelAdmin):
|
||||
list_display = ['name', 'long_name', 'manufacturer', 'avilable_batches']
|
||||
inlines = [
|
||||
BatchInline,
|
||||
PropogationInline,
|
||||
]
|
||||
list_editable = ['long_name', 'manufacturer']
|
||||
|
||||
@ -58,7 +58,7 @@ class StrainAdmin(admin.ModelAdmin):
|
||||
urls.append('<a href="{}">{}</a>'.format(url, url_text))
|
||||
return format_html(', '.join(urls))
|
||||
|
||||
avilable_batches.short_description = 'Available Batches'
|
||||
avilable_batches.short_description = 'Available Propogation'
|
||||
|
||||
@admin.register(Storage)
|
||||
class StorageAdmin(admin.ModelAdmin):
|
||||
@ -78,8 +78,8 @@ class ManufacturerAdmin(admin.ModelAdmin):
|
||||
if obj.website:
|
||||
return format_html("<a href='{url}'>{url}</a>", url=obj.website)
|
||||
|
||||
@admin.register(Batch)
|
||||
class BatchAdmin(admin.ModelAdmin):
|
||||
@admin.register(Propogation)
|
||||
class PropogationAdmin(admin.ModelAdmin):
|
||||
list_display = ['strain', 'consumed', 'source', 'parent_samples', 'production_date', 'avilable_samples', 'used_samples']
|
||||
form = YeastModelForm
|
||||
filter_horizontal = ['parent']
|
||||
@ -89,7 +89,7 @@ class BatchAdmin(admin.ModelAdmin):
|
||||
]
|
||||
|
||||
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:
|
||||
relate_samples = [x for x in Yeast.objects.all() if x.pitched_batch==form.instance.source_batch]
|
||||
for sample in relate_samples:
|
||||
|
@ -1,7 +1,7 @@
|
||||
from django import forms
|
||||
from django.urls import reverse
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from .models import Yeast, Batch, Strain
|
||||
from .models import Yeast, Propogation, Strain
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger('django')
|
||||
@ -30,7 +30,7 @@ class BatchAddForm(forms.ModelForm):
|
||||
# create meta class
|
||||
class Meta:
|
||||
# specify model to be used
|
||||
model = Batch
|
||||
model = Propogation
|
||||
|
||||
# specify fields to be used
|
||||
fields = [
|
||||
|
@ -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',
|
||||
),
|
||||
]
|
18
yeast/migrations/0003_rename_batch_propogation.py
Normal file
18
yeast/migrations/0003_rename_batch_propogation.py
Normal 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',
|
||||
),
|
||||
]
|
@ -48,7 +48,7 @@ class Strain(CustomModel):
|
||||
|
||||
@property
|
||||
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):
|
||||
# Return a string that represents the instance
|
||||
@ -68,13 +68,14 @@ class Storage(CustomModel):
|
||||
return self.name
|
||||
|
||||
|
||||
class Batch(CustomModel):
|
||||
class Propogation(CustomModel):
|
||||
"""
|
||||
Stores a batch of :model:`yeast.Yeast` of a single :model:`yeast.Strain`.
|
||||
|
||||
Can be a single purchased pack, or multiple vials
|
||||
to be frozen from a starter.
|
||||
"""
|
||||
|
||||
BATCH_TYPES = {
|
||||
'ST': 'Store',
|
||||
'PR': 'Propogated',
|
||||
@ -89,7 +90,7 @@ class Batch(CustomModel):
|
||||
notes = models.TextField(max_length=500, blank=True, null=True)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super(Batch, self).save(*args, **kwargs)
|
||||
super(Propogation, self).save(*args, **kwargs)
|
||||
if self.source_batch:
|
||||
relate_samples = [x for x in Yeast.objects.all() if x.pitched_batch==self.source_batch]
|
||||
for sample in relate_samples:
|
||||
@ -97,19 +98,19 @@ class Batch(CustomModel):
|
||||
|
||||
@property
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
def beer_name(self):
|
||||
@ -132,11 +133,11 @@ class Batch(CustomModel):
|
||||
|
||||
@property
|
||||
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
|
||||
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):
|
||||
# Return a string that represents the instance
|
||||
@ -148,7 +149,7 @@ class Yeast(CustomModel):
|
||||
Store an individual sample of yeast.
|
||||
"""
|
||||
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)
|
||||
storage = models.ForeignKey(Storage, on_delete=models.CASCADE)
|
||||
cellcount = models.IntegerField(default=100)
|
||||
@ -163,7 +164,7 @@ class Yeast(CustomModel):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return '{} {}'.format(self.id, self.batch.strain.name)
|
||||
return '{} {}'.format(self.id, self.propogation.strain.name)
|
||||
|
||||
@property
|
||||
def age(self):
|
||||
@ -174,7 +175,7 @@ class Yeast(CustomModel):
|
||||
else:
|
||||
end_date = timezone.now().date()
|
||||
|
||||
return abs((self.batch.production_date-end_date).days)
|
||||
return abs((self.propogation.production_date-end_date).days)
|
||||
|
||||
@property
|
||||
def viability(self):
|
||||
@ -183,13 +184,4 @@ class Yeast(CustomModel):
|
||||
|
||||
def __str__(self):
|
||||
# Return a string that represents the instance
|
||||
return '{} {}'.format(self.id, self.batch.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)
|
||||
return '{} {}'.format(self.id, self.propogation.strain.name)
|
||||
|
@ -49,7 +49,7 @@
|
||||
</fieldset>
|
||||
</div>
|
||||
<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>
|
||||
<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">
|
||||
|
@ -16,7 +16,7 @@ input, label {
|
||||
|
||||
<div class="container" id="main">
|
||||
|
||||
<h3>Batches</h3>
|
||||
<h3>Yeast Propogations</h3>
|
||||
|
||||
<form action="{% url 'yeast:get_batch' %}" method="post">
|
||||
{% csrf_token %}
|
||||
@ -37,7 +37,7 @@ input, label {
|
||||
<div class="container m-2">
|
||||
<div class="row">
|
||||
<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%;">
|
||||
{% for batch in batches %}
|
||||
{% if not batch.consumed %}
|
||||
@ -56,7 +56,7 @@ input, label {
|
||||
{% 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>
|
||||
{% elif batch.source == 'ST' %}
|
||||
<th>Batch Source</th><td>Purchased from Store</td>
|
||||
<th>Yeast Source</th><td>Purchased from Store</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
<tr>
|
||||
@ -86,7 +86,7 @@ input, label {
|
||||
</div>
|
||||
</div>
|
||||
<div class="container m-2">
|
||||
<input type="submit" value="Go to Batch Page">
|
||||
<input type="submit" value="Go to Yeast Propogation Page">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -2,33 +2,143 @@
|
||||
{% load mathfilters %}
|
||||
{% block title %}Yeast Samples{% endblock %}
|
||||
|
||||
{% block jumbotron %}Yeast Sample:{% endblock %}
|
||||
{% block jumbotronsub %}<a href="{% url 'admin:yeast_yeast_change' sample.id %}">{{ sample.id }}</a>{% endblock %}
|
||||
{% block style %}
|
||||
.table td.fit,
|
||||
.table th.fit {
|
||||
white-space: nowrap;
|
||||
width: 1%;
|
||||
}
|
||||
{% endblock %}
|
||||
|
||||
{% block jumbotron %}Yeast Sample{% endblock %}
|
||||
{% block jumbotronsub %}
|
||||
<table class="table table-borderless">
|
||||
<tbody>
|
||||
<tr><th class="fit">{{ batch.strain.manufacturer.name }} {{ batch.strain.name }}</th><td><a href="{% url 'admin:yeast_yeast_change' sample.id %}">{{ sample.id }}</a></td></tr>
|
||||
<tr><th class="fit">Batch Source</th>
|
||||
<td>{{ batch.get_source_display }}
|
||||
{% if batch.source_batch %}
|
||||
from <a href="{{ batch.beer_url }}" target="_blank" rel="noopener noreferrer">#{{ batch.beer_num }}: {{ batch.beer_name }}</a><br>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr><th class="fit">Production Date</th><td>{{ sample.batch.production_date }}</td></tr>
|
||||
<tr><th class="fit">Storage</th>
|
||||
<td>
|
||||
{{ sample.storage }}
|
||||
{% if sample.pitched %}
|
||||
(Pitched <a href="{{ sample.pitched_batch.brewfather_url }}" target="_blank" rel="noopener noreferrer">#{{ sample.pitched_batch.brewfather_num }}: {{ sample.pitched_batch.brewfather_name }}</a>)
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<!-- Information Header -->
|
||||
<div class="container">
|
||||
|
||||
<h3>{{ batch.strain.name }}</h3>
|
||||
<b>Batch Source:</b> {{ batch.get_source_display }}
|
||||
{% if batch.source_batch %}
|
||||
from <a href="{{ batch.beer_url }}" target="_blank" rel="noopener noreferrer">#{{ batch.beer_num }}: {{ batch.beer_name }}</a>
|
||||
{% endif %}<br>
|
||||
<b>Production Date:</b> {{ sample.batch.production_date }}<br>
|
||||
</div> <!-- /container -->
|
||||
<!-- End Information Header -->
|
||||
|
||||
<!-- Main Data Container -->
|
||||
<div class="container mt-4 mb-4">
|
||||
<div class="row">
|
||||
|
||||
<!-- Tabbed Forms -->
|
||||
<div class="col-lg-6" style="{% if sample.pitched %}display:none{% endif %}">
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-bs-toggle="tab" href="#propogate">Propogate Sample</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-bs-toggle="tab" href="#pitch">Pitch Sample</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div id="propogate" class="container tab-pane active"><br>
|
||||
<!-- Sample Propogation Form -->
|
||||
<div class="container" style="border:1px solid #cecece;">
|
||||
<form >
|
||||
<legend>Propogate Yeast Sample</legend>
|
||||
<div class="mb-3">
|
||||
<label for="new-samples" class="form-label"># New Samples</label>
|
||||
<input type="number" class="form-control" id="new-samples" aria-describedby="numHelp">
|
||||
<div id="numHelp" class="form-text">New samples will be automatically created</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="parent" class="form-label">Default Storage Method</label>
|
||||
<select class="form-select" id="parent" name="parent" aria-describedby="storageHelp">
|
||||
<option selected>-- Choose an Option --</option>
|
||||
{% for method in storage %}
|
||||
<option value="{{ method.id }}">{{ method }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div id="storageHelp" class="form-text">How will samples be stored?</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
<!-- End Sample Propogation Form -->
|
||||
</div>
|
||||
<div id="pitch" class="container tab-pane fade"><br>
|
||||
<!-- Sample Pitch Form -->
|
||||
<div class="container" style="border:1px solid #cecece;">
|
||||
<form >
|
||||
<legend>Pitch Yeast Sample</legend>
|
||||
<div class="mb-3">
|
||||
<label for="beer-batch" class="form-label">Beer Batch</label>
|
||||
<select class="form-select" id="beer-batch" name="beer-batch" aria-describedby="batchHelp">
|
||||
<option selected>Beer Batch</option>
|
||||
<option value="1">#16 So So Special</option>
|
||||
<option value="2">#17 Some other beer</option>
|
||||
<option value="3">#18 Another Thing</option>
|
||||
</select>
|
||||
<div id="batchHelp" class="form-text">Select batch of beer sample is pitched into.</div>
|
||||
</div>
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" class="form-check-input" id="starterCheck">
|
||||
<label class="form-check-label" for="starterCheck">Pitched into starter?</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
<!-- End Sample Pitch Form -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- End Tabbed Forms -->
|
||||
|
||||
<!-- Remain Sample List -->
|
||||
<div class="col-lg-6">
|
||||
{% if batch.remaining_samples %}<h4>Other Remaining Batch Samples</h4>
|
||||
<ul>
|
||||
{% for s in batch.remaining_samples|dictsort:"storage.name" %}
|
||||
{% if s.id != sample.id %}
|
||||
<li><a href="{% url 'yeast:yeast' s.id %}">{{ s.id }}</a> - {{ s.storage.name }} for {{ s.age }} days, {{ s.viability|mul:100|floatformat:1 }}%</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if batch.used_samples %}<h4>Other Samples Used</h4>
|
||||
<ul>
|
||||
{% for s in batch.used_samples %}
|
||||
{% if s.id != sample.id %}
|
||||
<li><a href="{% url 'yeast:yeast' s.id %}">{{ s.id }}</a></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
<!-- End Remain Sample List -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Main Data Container -->
|
||||
|
||||
<p><p>
|
||||
{% if batch.remaining_samples %}<h4>Batch Samples Remaining</h4>
|
||||
<ul>
|
||||
{% for sample in batch.remaining_samples %}
|
||||
<li><a href="{% url 'yeast:yeast' sample.id %}">{{ sample.id }}</a> - Storage method: {{ sample.storage.name }} for {{ sample.age }} days, Viability: {{ sample.viability|mul:100|floatformat:1 }}%</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if batch.used_samples %}<h4>Batch Samples Used</h4>
|
||||
<ul>
|
||||
{% for sample in batch.used_samples %}
|
||||
<li><a href="{% url 'yeast:yeast' sample.id %}">{{ sample.id }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div> <!-- /container -->
|
||||
{% endblock %}
|
||||
|
@ -6,7 +6,7 @@ from django.urls import reverse
|
||||
from django.http import JsonResponse
|
||||
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 yeast.forms import BatchAddForm, StrainAddForm
|
||||
|
||||
@ -18,13 +18,15 @@ class YeastListView(ListView):
|
||||
model = Yeast
|
||||
|
||||
class BatchListView(ListView):
|
||||
model = Batch
|
||||
model = Propogation
|
||||
|
||||
def sample(request, yeast_id):
|
||||
|
||||
sample = get_object_or_404(Yeast, pk=yeast_id)
|
||||
sample_batch = get_object_or_404(Batch, pk=sample.batch_id)
|
||||
return render(request, 'yeast/sample.html', {'sample': sample, 'batch':sample_batch})
|
||||
return render(request, 'yeast/sample.html', {
|
||||
'sample': sample,
|
||||
'batch': get_object_or_404(Propogation, pk=sample.batch_id),
|
||||
'storage': list(Storage.objects.all()),
|
||||
})
|
||||
|
||||
# @login_required
|
||||
# def get_batches(request):
|
||||
@ -43,19 +45,19 @@ def get_batch(request):
|
||||
return redirect(re_url)
|
||||
|
||||
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):
|
||||
"""
|
||||
Display a batch of yeast samples.
|
||||
|
||||
``Batch``
|
||||
An instance of :model:`yeast.Batch`.
|
||||
``Propogation``
|
||||
An instance of :model:`yeast.Propogation`.
|
||||
|
||||
``Template``
|
||||
: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})
|
||||
|
||||
def batch_labels(request, batch_id):
|
||||
@ -65,11 +67,11 @@ def batch_labels(request, batch_id):
|
||||
**Context**
|
||||
|
||||
``Batch``
|
||||
An instance of :model:`yeast.Batch`.
|
||||
An instance of :model:`yeast.Propogation`.
|
||||
"""
|
||||
skip_count = request.POST.get("skip_count", "")
|
||||
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()))
|
||||
|
||||
# Create the HttpResponse object with the appropriate PDF headers.
|
||||
@ -96,7 +98,7 @@ def batch_labels(request, batch_id):
|
||||
return response
|
||||
|
||||
class addBatch(CreateView):
|
||||
model = Batch
|
||||
model = Propogation
|
||||
form_class = BatchAddForm
|
||||
|
||||
def get_success_url(self):
|
||||
|
Loading…
Reference in New Issue
Block a user