Compare commits
4 Commits
12fca700da
...
1986d9fbd0
Author | SHA1 | Date | |
---|---|---|---|
1986d9fbd0 | |||
671ea27d9f | |||
b6be827d14 | |||
2f33a27e47 |
18
beer/migrations/0012_recipe_fermentables.py
Normal file
18
beer/migrations/0012_recipe_fermentables.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0.6 on 2024-06-21 13:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('beer', '0011_rename_batchrecipe_recipe'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='recipe',
|
||||
name='fermentables',
|
||||
field=models.ManyToManyField(through='beer.RecipeFermentable', to='beer.fermentable'),
|
||||
),
|
||||
]
|
@ -1,4 +1,5 @@
|
||||
from django.db import models
|
||||
from django.db.models import Sum, Q
|
||||
from django.utils import timezone
|
||||
from django_cryptography.fields import encrypt
|
||||
from django.core.validators import MinValueValidator
|
||||
@ -106,25 +107,28 @@ class Recipe(CustomModel):
|
||||
max_digits=6, decimal_places=2, default=75)
|
||||
batch_size = models.DecimalField(
|
||||
max_digits=6, decimal_places=2, default=11)
|
||||
fermentables = models.ManyToManyField(
|
||||
'Fermentable', through='RecipeFermentable')
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Recipe'
|
||||
verbose_name_plural = 'Recipes'
|
||||
|
||||
@property
|
||||
def fermentables(self):
|
||||
return [x for x in list(self.recipefermentable_set.all())]
|
||||
|
||||
@property
|
||||
def fermentable_weight(self):
|
||||
return sum([x.quantity for x in self.fermentables])
|
||||
"""Weight of all fermentables attached to recipe."""
|
||||
aggregate = self.recipefermentable_set.all().aggregate(Sum('quantity'))
|
||||
return aggregate['quantity__sum']
|
||||
|
||||
@property
|
||||
def hops(self):
|
||||
return [x for x in list(self.recipehop_set.all())]
|
||||
def hop_weight(self):
|
||||
"""Weight of all fermentables attached to recipe."""
|
||||
aggregate = self.recipehop_set.all().aggregate(Sum('quantity'))
|
||||
return aggregate['quantity__sum']
|
||||
|
||||
@property
|
||||
def final_volume(self):
|
||||
"""Return final volume (after boil)."""
|
||||
return (float(self.batch_size)
|
||||
+ self.hop_water_loss
|
||||
+ self.net_kettle_deadspace
|
||||
@ -132,44 +136,51 @@ class Recipe(CustomModel):
|
||||
|
||||
@property
|
||||
def sugar_yield(self):
|
||||
"""Return point yield of all non-mashed ingredients."""
|
||||
ferm_yield = 0
|
||||
|
||||
sugars = (x for x in self.fermentables
|
||||
if x.fermentable.fermentable_type == 3) # Is sugar
|
||||
ferms = self.recipefermentable_set.all().select_related('fermentable')
|
||||
sugars = ferms.filter(fermentable__fermentable_type=3)
|
||||
|
||||
for f in sugars:
|
||||
ferm_yield += f.quantity * (f.fermentable.potential - 1) * 1000
|
||||
ferm_yield += f.ferm_yield
|
||||
|
||||
return float(ferm_yield)
|
||||
|
||||
@property
|
||||
def mash_yield(self):
|
||||
"""Return point yield of all mashed ingredients."""
|
||||
mash_yield = 0
|
||||
|
||||
mashed = (x for x in self.fermentables
|
||||
if x.fermentable.fermentable_type != 3) # Is not sugar
|
||||
ferms = self.recipefermentable_set.all().select_related('fermentable')
|
||||
# Is not sugar (3)
|
||||
mashed = ferms.filter(~Q(fermentable__fermentable_type=3))
|
||||
|
||||
for f in mashed:
|
||||
mash_yield += (f.quantity * (self.efficiency / 100)
|
||||
* (f.fermentable.potential - 1) * 1000)
|
||||
mash_yield += f.ferm_yield
|
||||
|
||||
return float(mash_yield)
|
||||
|
||||
@property
|
||||
def original_sg(self):
|
||||
"""Return original gravity."""
|
||||
total_yield = self.sugar_yield + self.mash_yield
|
||||
return round(1 + total_yield / self.final_volume / 1000, 3)
|
||||
gravity_points = total_yield/self.final_volume
|
||||
return round(1 + gravity_points/1000, 3)
|
||||
|
||||
@property
|
||||
def pre_boil_sg(self):
|
||||
"""Return pre-boil gravity."""
|
||||
total_yield = self.sugar_yield + self.mash_yield
|
||||
return round(1 + total_yield / (self.final_volume
|
||||
+ self.boil_off_gph) / 1000, 3)
|
||||
total_water = self.final_volume+self.boil_off_gph
|
||||
gravity_points = total_yield/total_water
|
||||
return round(1 + gravity_points/1000, 3)
|
||||
|
||||
@property
|
||||
def hop_water_loss(self):
|
||||
hop_absorption = .025 # gallons per ounce
|
||||
return sum([float(x.quantity) * hop_absorption for x in self.hops])
|
||||
return float(sum(
|
||||
x.quantity*x.trub_volume for x in self.recipehop_set.all()
|
||||
))
|
||||
|
||||
@property
|
||||
def net_kettle_deadspace(self):
|
||||
@ -204,11 +215,12 @@ class Recipe(CustomModel):
|
||||
|
||||
@property
|
||||
def ibu_tinseth(self):
|
||||
return sum([x.ibu_tinseth for x in self.hops])
|
||||
return sum(x.ibu_tinseth for x in self.recipehop_set.all())
|
||||
|
||||
@property
|
||||
def srm(self):
|
||||
color_total = sum([x.srm for x in self.fermentables])
|
||||
color_total = sum(x.lovibond_contributed
|
||||
for x in self.recipefermentable_set.all())
|
||||
return 1.4922*(color_total**0.6859)
|
||||
|
||||
@property
|
||||
@ -291,11 +303,20 @@ class RecipeFermentable(CustomModel):
|
||||
return float(100 * self.quantity / self.recipe.fermentable_weight)
|
||||
|
||||
@property
|
||||
def srm(self):
|
||||
def lovibond_contributed(self):
|
||||
srm_calc = (float(self.fermentable.lovibond)
|
||||
* float(self.quantity) / self.recipe.final_volume)
|
||||
return round(srm_calc, 1)
|
||||
|
||||
@property
|
||||
def ferm_yield(self):
|
||||
potential_yield = self.quantity * (self.fermentable.potential-1) * 1000
|
||||
|
||||
if self.fermentable.fermentable_type == 3:
|
||||
return potential_yield
|
||||
else:
|
||||
return potential_yield * (self.recipe.efficiency/100)
|
||||
|
||||
|
||||
class Hop(CustomIngredient):
|
||||
uses = {
|
||||
@ -343,22 +364,31 @@ class RecipeHop(CustomModel):
|
||||
4: 1.4, # CO2 Extract
|
||||
}
|
||||
|
||||
ibu = 0
|
||||
hop_bonus = type_bonus[self.hop.hop_type]
|
||||
|
||||
average_wort_sg = (((self.recipe.pre_boil_sg - 1)
|
||||
+ (self.recipe.original_sg - 1)) / 2)
|
||||
average_wort_sg = (((self.recipe.pre_boil_sg-1)
|
||||
+ (self.recipe.original_sg-1)) / 2)
|
||||
|
||||
if self.use == 1:
|
||||
conc = (((float(self.hop.alpha) / 100)
|
||||
* float(self.quantity))
|
||||
* 7490 / self.recipe.final_volume)
|
||||
util = ((type_bonus[self.hop.hop_type]
|
||||
* 1.65 * (0.000125**average_wort_sg))
|
||||
* ((1-2.71828182845904**(-0.04 * self.time))/4.15))
|
||||
conc = (float((self.hop.alpha/100) * self.quantity)
|
||||
* 7490/self.recipe.final_volume)
|
||||
util = (hop_bonus*1.65*0.000125**average_wort_sg
|
||||
* ((1-2.71828182845904**(-0.04*self.time)) / 4.15))
|
||||
ibu = conc * util
|
||||
else:
|
||||
ibu = 0
|
||||
|
||||
return float(ibu)
|
||||
|
||||
@property
|
||||
def trub_volume(self):
|
||||
if self.hop.hop_type == 1:
|
||||
return self.recipe.equipment.pellet_hop_trub
|
||||
elif self.hop.hop_type in [2, 3]:
|
||||
return self.recipe.equipment.leaf_hop_trub
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
class Misc(CustomIngredient):
|
||||
uses = {
|
||||
|
@ -10,6 +10,11 @@ input, label {
|
||||
.container-beer {
|
||||
background: {{ recipe.srm_hex }};
|
||||
}
|
||||
|
||||
p.smaller {
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}Recipes{% endblock %}
|
||||
@ -19,7 +24,7 @@ input, label {
|
||||
{% block jumbotronsub %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg d-flex justify-content-between" style="border:1px solid #cecece; margin-right:.5em; margin-left:.5em">
|
||||
<div class="col-lg d-flex justify-content-between">
|
||||
<div>
|
||||
<div class="container-beer"><img src="{% static "beer_back.png" %}" alt="" class="img-responsive d-none d-sm-block"></div>
|
||||
</div>
|
||||
@ -32,9 +37,15 @@ input, label {
|
||||
<dd>All Grain</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="col-lg-4" style="border:1px solid #cecece; margin-right:.5em; margin-left:.5em">
|
||||
|
||||
<div class="text-truncate">Equipment: {{ recipe.equipment.name }}</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="d-flex justify-content-between bg-dark text-white">
|
||||
<div class="text-truncate ms-1 my-1">{{ recipe.equipment.name }}</div>
|
||||
<div>
|
||||
<button type="button" class="btn btn-dark btn-sm"><i class="fas fa-scale-unbalanced-flip"></i></button>
|
||||
<button type="button" class="btn btn-dark btn-sm"><i class="fas fa-arrow-right-arrow-left"></i></button>
|
||||
<button type="button" class="btn btn-dark btn-sm"><i class="fas fa-pen-to-square"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<b>Batch Size:</b> {{ recipe.batch_size }} gal <b>Actual Volume:</b> {{ recipe.final_volume|floatformat:2 }}<br>
|
||||
<b>Mash Efficiency:</b> {{ recipe.efficiency|floatformat:2 }} %
|
||||
@ -48,7 +59,7 @@ input, label {
|
||||
<dd>{{ recipe.efficiency|floatformat:2 }} %</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="col-xl-3" style="border:1px solid #cecece; margin-right:.5em; margin-left:.5em">
|
||||
<div class="col-xl-3">
|
||||
Style Data
|
||||
</div>
|
||||
</div>
|
||||
@ -64,11 +75,28 @@ input, label {
|
||||
<!-- Fermentables -->
|
||||
<div class="col-md">
|
||||
<div class="container-fluid">
|
||||
<div class="container-fluid bg-dark text-white">Fermentables ({{ fermentable_weight|floatformat:2 }} lbs)</div>
|
||||
<table class="table table-sm ">
|
||||
<div class="d-flex justify-content-between bg-dark text-white">
|
||||
<div class="ms-2 my-1">Fermentables ({{ recipe.fermentable_weight|floatformat:2 }} lbs)</div>
|
||||
<div>
|
||||
<button type="button" class="btn btn-dark btn-sm"><b>%</b></button>
|
||||
<button type="button" class="btn btn-dark btn-sm"><b>OG</b></button>
|
||||
<button type="button" class="btn btn-dark btn-sm"><i class="fa fa-plus"></i><b>ADD</b></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-sm table-hover">
|
||||
|
||||
<caption>
|
||||
<p class="text-end smaller">
|
||||
Pre-Boil Gravity: <b>{{ recipe.pre_boil_sg }}</b><br>
|
||||
Original Gravity: <b>{{ recipe.original_sg }}</b><br>
|
||||
Color: <b>{{ recipe.srm|floatformat:0 }} SRM</b>
|
||||
</p>
|
||||
</caption>
|
||||
|
||||
<tbody>
|
||||
{% for f in recipe.recipefermentable_set.all %}
|
||||
<tr>
|
||||
<tr onclick="window.location='{% url 'beer:update_fermentable' f.fermentable.id %}';">
|
||||
<td>{{ f.quantity|floatformat:2 }} lb</td>
|
||||
<td>{{ f.fermentable.name }}<br>
|
||||
<span class="text-muted">{{ f.fermentable.get_fermentable_type_display }} {{ f.srm }} SRM</span>
|
||||
@ -78,11 +106,7 @@ input, label {
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="text-end small">
|
||||
Pre-Boil Gravity: <b>{{ recipe.pre_boil_sg }}</b><br>
|
||||
Original Gravity: <b>{{ recipe.original_sg }}</b><br>
|
||||
Color: <b>{{ recipe.srm|floatformat:0 }} SRM</b>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -90,11 +114,24 @@ input, label {
|
||||
<!-- Hops -->
|
||||
<div class="col-md">
|
||||
<div class="container-fluid">
|
||||
<div class="container-fluid bg-dark text-white">Hops ({{ hop_weight|floatformat:2 }} oz)</div>
|
||||
<table class="table table-sm ">
|
||||
<div class="d-flex justify-content-between bg-dark text-white">
|
||||
<div class="ms-2 my-1">Hops ({{ recipe.hop_weight|floatformat:2 }} oz)</div>
|
||||
<div>
|
||||
<button type="button" class="btn btn-dark btn-sm"><b>IBU</b></button>
|
||||
<button type="button" class="btn btn-dark btn-sm"><i class="fa fa-plus"></i><b>ADD</b></button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-sm table-hover">
|
||||
<caption>
|
||||
<p class="text-end smaller">
|
||||
Total IBU: <b>{{ recipe.ibu_tinseth|floatformat:1 }}</b><br>
|
||||
BU/GU: <b>{{ recipe.bu_gu|floatformat:2 }}</b><br>
|
||||
RBR: <b>{{ recipe.rbr|floatformat:2 }}</b>
|
||||
</p>
|
||||
</caption>
|
||||
<tbody>
|
||||
{% for h in recipe.recipehop_set.all %}
|
||||
<tr>
|
||||
<tr onclick="window.location='{% url 'beer:update_hop' h.hop.id %}';">
|
||||
<td>{{ h.quantity|floatformat:2 }} oz</td>
|
||||
<td>{{ h.hop.name }} {{ h.hop.alpha|floatformat:1 }} %<br>
|
||||
<span class="text-muted">{{ h.hop.get_hop_type_display }} {{ h.ibu_tinseth|floatformat:1 }} IBU</span>
|
||||
@ -103,11 +140,7 @@ input, label {
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="text-end small">
|
||||
Total IBU: <b>{{ recipe.ibu_tinseth|floatformat:1 }}</b><br>
|
||||
BU/GU: <b>{{ recipe.bu_gu|floatformat:2 }}</b><br>
|
||||
RBR: <b>{{ recipe.rbr|floatformat:2 }}</b>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -118,7 +151,12 @@ input, label {
|
||||
<!-- Misc -->
|
||||
<div class="col-md">
|
||||
<div class="container-fluid">
|
||||
<div class="container-fluid bg-dark text-white">Misc.</div>
|
||||
<div class="d-flex justify-content-between bg-dark text-white">
|
||||
<div class="ms-2 my-1">Misc.</div>
|
||||
<div>
|
||||
<button type="button" class="btn btn-dark btn-sm"><i class="fa fa-plus"></i><b>ADD</b></button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-sm">
|
||||
<tbody>
|
||||
{% for m in recipe.recipemisc_set.all %}
|
||||
@ -131,7 +169,12 @@ input, label {
|
||||
<!-- Yeast -->
|
||||
<div class="col-md">
|
||||
<div class="container-fluid">
|
||||
<div class="container-fluid bg-dark text-white">Yeast</div>
|
||||
<div class="d-flex justify-content-between bg-dark text-white">
|
||||
<div class="ms-2 my-1">Yeast</div>
|
||||
<div>
|
||||
<button type="button" class="btn btn-dark btn-sm"><i class="fa fa-plus"></i><b>ADD</b></button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-sm">
|
||||
<tbody>
|
||||
{% for y in recipe.recipeyeast_set.all %}
|
||||
@ -149,7 +192,13 @@ input, label {
|
||||
<!-- Mash -->
|
||||
<div class="col-md">
|
||||
<div class="container-fluid">
|
||||
<div class="container-fluid bg-dark text-white">Mash Profile {{ recipe.mash.name }}</div>
|
||||
<div class="d-flex justify-content-between bg-dark text-white">
|
||||
<div class="ms-2 my-1">Mash Profile: {{ recipe.mash.name }}</div>
|
||||
<div>
|
||||
<button type="button" class="btn btn-dark btn-sm"><i class="fas fa-arrow-right-arrow-left"></i></button>
|
||||
<button type="button" class="btn btn-dark btn-sm"><i class="fas fa-pen-to-square"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-sm ">
|
||||
<tbody>
|
||||
{% for step in recipe.mash.mashstep_set.all %}
|
||||
@ -165,14 +214,13 @@ input, label {
|
||||
<!-- Fermentation -->
|
||||
<div class="col-md">
|
||||
<div class="container-fluid">
|
||||
<div class="container-fluid bg-dark text-white">Fermentation Profile</div>
|
||||
<table class="table table-sm">
|
||||
<tbody>
|
||||
<!-- {% for y in recipe.recipeyeast_set.all %} -->
|
||||
<!-- <tr><td>{{ y.yeast.name }}</td></tr> -->
|
||||
<!-- {% endfor %} -->
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="d-flex justify-content-between bg-dark text-white">
|
||||
<div class="ms-2 my-1">Fermentation Profile</div>
|
||||
<div>
|
||||
<button type="button" class="btn btn-dark btn-sm"><i class="fas fa-arrow-right-arrow-left"></i></button>
|
||||
<button type="button" class="btn btn-dark btn-sm"><i class="fas fa-pen-to-square"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
14
beer/templates/beer/update_fermentable.html
Normal file
14
beer/templates/beer/update_fermentable.html
Normal file
@ -0,0 +1,14 @@
|
||||
{% extends "base.html" %}
|
||||
{% load mathfilters %}
|
||||
{% load funcs %}
|
||||
{% load static %}
|
||||
|
||||
|
||||
|
||||
{% block title %}Recipes{% endblock %}
|
||||
|
||||
{% block jumbotron %}{{ data.name }}{% endblock %}
|
||||
|
||||
{% block jumbotronsub %}
|
||||
{{ data.potential }}
|
||||
{% endblock %}
|
14
beer/templates/beer/update_hop.html
Normal file
14
beer/templates/beer/update_hop.html
Normal file
@ -0,0 +1,14 @@
|
||||
{% extends "base.html" %}
|
||||
{% load mathfilters %}
|
||||
{% load funcs %}
|
||||
{% load static %}
|
||||
|
||||
|
||||
|
||||
{% block title %}Recipes{% endblock %}
|
||||
|
||||
{% block jumbotron %}{{ data.name }}{% endblock %}
|
||||
|
||||
{% block jumbotronsub %}
|
||||
{{ data.alpha }} %
|
||||
{% endblock %}
|
@ -1,10 +1,13 @@
|
||||
from django.urls import path
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
from .views import home, view_recipe
|
||||
from .views import home, view_recipe, update_ferm, update_hop
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('', home, name='home'),
|
||||
path('recipes/<int:recipe_id>/', view_recipe, name='recipe'),
|
||||
path('ingredients/fermentables/<int:ferm_id>',
|
||||
update_ferm, name='update_fermentable'),
|
||||
path('ingredients/hops/<int:hop_id>', update_hop, name='update_hop'),
|
||||
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
|
||||
from .models import UserProfile, Recipe, Batch
|
||||
from .models import UserProfile, Recipe, Batch, Fermentable, Hop
|
||||
from .extras import get_batches
|
||||
|
||||
import json
|
||||
@ -46,8 +46,26 @@ def view_recipe(request, recipe_id):
|
||||
|
||||
context = {
|
||||
'recipe': recipe,
|
||||
'fermentable_weight': sum([x.quantity for x in recipe.fermentables]),
|
||||
'hop_weight': sum([x.quantity for x in recipe.hops]),
|
||||
}
|
||||
|
||||
return render(request, 'beer/recipe.html', context)
|
||||
|
||||
|
||||
def update_ferm(request, ferm_id):
|
||||
fermentable = get_object_or_404(Fermentable, pk=ferm_id)
|
||||
|
||||
context = {
|
||||
'data': fermentable,
|
||||
}
|
||||
|
||||
return render(request, 'beer/update_fermentable.html', context)
|
||||
|
||||
|
||||
def update_hop(request, hop_id):
|
||||
hop = get_object_or_404(Hop, pk=hop_id)
|
||||
|
||||
context = {
|
||||
'data': hop,
|
||||
}
|
||||
|
||||
return render(request, 'beer/update_hop.html', context)
|
||||
|
@ -37,6 +37,7 @@ INSTALLED_APPS = [
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.flatpages',
|
||||
'fontawesomefree',
|
||||
'mathfilters',
|
||||
'yeast.apps.YeastLabConfig',
|
||||
'beer.apps.BeerConfig',
|
||||
|
@ -4,6 +4,7 @@ django-cryptography-django5==2.2
|
||||
django-mathfilters==1.0.0
|
||||
docutils==0.21.2
|
||||
environs==11.0.0
|
||||
fontawesomefree==6.5.1
|
||||
gunicorn==22.0.0
|
||||
pip-chill==1.0.3
|
||||
psycopg2-binary==2.9.9
|
||||
|
2
run.sh
2
run.sh
@ -1,6 +1,8 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
source .env/bin/activate
|
||||
find -name "*.py" -not -name "manage.py" -not -path "./.env/*" -not -path "*/migrations/*" -exec python -m flake8 {} \;
|
||||
|
||||
pip install --upgrade -r requirements.txt > /dev/null
|
||||
python manage.py makemigrations
|
||||
python manage.py migrate
|
||||
|
@ -6,7 +6,9 @@
|
||||
|
||||
<!-- CSS only -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||
|
||||
{% load static %}
|
||||
<link href="{% static 'fontawesomefree/css/fontawesome.css' %}" rel="stylesheet" type="text/css">
|
||||
<link href="{% static 'fontawesomefree/css/solid.css' %}" rel="stylesheet" type="text/css">
|
||||
<!-- JS, Popper.js, and jQuery -->
|
||||
<!-- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" -->
|
||||
<!-- integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" -->
|
||||
|
@ -11,26 +11,10 @@ Add Batch
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<form action="" method="post">{% csrf_token %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="Submit" />
|
||||
</form>
|
||||
|
||||
<!-- <form action="addbatch/" method="post">
|
||||
{% csrf_token %}
|
||||
production_date:<br>
|
||||
<input name="production_date">
|
||||
<br><br>
|
||||
strain:<br>
|
||||
<input name="strain">
|
||||
<br><br>
|
||||
source:<br>
|
||||
<input name="source">
|
||||
<br><br>
|
||||
data_web:<br>
|
||||
<input name="data_web">
|
||||
<br><br>
|
||||
<input type="submit" value="Submit">
|
||||
</form> -->
|
||||
</div>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user