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, Propogation from yeast.forms import YeastModelForm from config.extras import BREWFATHER_APP_ROOT class PropogationInline(admin.TabularInline): model = Propogation extra = 0 class SampleInline(admin.TabularInline): model = Yeast extra = 0 class StrainInline(admin.TabularInline): model = Strain extra = 5 class ParentInline(admin.TabularInline): verbose_name = 'Parent Samples' model = Propogation.parent.through @admin.register(Yeast) class YeastAdmin(admin.ModelAdmin): 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): if obj.pitched_batch: bf_id = obj.pitched_batch.brewfather_id url_string = ('' '{batch_id}') return format_html( url_string, batch_id=bf_id, root=BREWFATHER_APP_ROOT) def url(self, obj): if obj.data_web: return format_html("{url}", url=obj.data_web) @admin.register(Strain) class StrainAdmin(admin.ModelAdmin): list_display = ['name', 'long_name', 'manufacturer', 'avilable_batches'] inlines = [ PropogationInline, ] list_editable = ['long_name', 'manufacturer'] def avilable_batches(self, obj): related_objs = [x for x in obj.batch_set.all() if not x.consumed] urls = [] for related_obj in related_objs: url_text = '{}: {}'.format(related_obj.get_source_display( ), related_obj.production_date.strftime("%Y-%m-%d")) # replace 'myapp' with your app name url = reverse('admin:yeast_batch_change', args=[related_obj.id]) urls.append('{}'.format(url, url_text)) return format_html(', '.join(urls)) avilable_batches.short_description = 'Available Propogation' @admin.register(Storage) class StorageAdmin(admin.ModelAdmin): list_display = ['name', 'viability_loss', 'viability_interval'] inlines = [ SampleInline, ] @admin.register(Manufacturer) class ManufacturerAdmin(admin.ModelAdmin): list_display = ['name', 'url'] inlines = [ StrainInline, ] def url(self, obj): if obj.website: return format_html("{url}", url=obj.website) @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'] inlines = [ # ParentInline, SampleInline, ] def save_related(self, 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: form.instance.parent.add(sample) def parent_samples(self, obj): obj.parent.all() def used_samples(self, obj): related_objs = list(set(obj.yeast_set.all()) - set(obj.remaining_samples)) urls = [] for related_obj in related_objs: url = reverse('admin:yeast_yeast_change', args=[related_obj.id]) urls.append('{}'.format(url, related_obj)) return format_html(', '.join(urls)) used_samples.short_description = 'Used Samples' def avilable_samples(self, obj): related_objs = obj.remaining_samples urls = [] for related_obj in related_objs: # replace 'myapp' with your app name url = reverse('admin:yeast_yeast_change', args=[related_obj.id]) urls.append('{}'.format(url, related_obj)) return format_html(', '.join(urls)) avilable_samples.short_description = 'Available Samples' app = apps.get_app_config('yeast') for model_name, model in app.models.items(): try: admin.site.register(model) except admin.exceptions.AlreadyRegistered: pass