Implement package-detail view
This commit is contained in:
		@@ -292,3 +292,8 @@ class DistributorNumberFormSet(forms.BaseModelFormSet):
 | 
			
		||||
            if commit:
 | 
			
		||||
                instance.save()
 | 
			
		||||
        return instances
 | 
			
		||||
 | 
			
		||||
class PackageForm(forms.ModelForm):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = parts_models.Package
 | 
			
		||||
        fields = '__all__'
 | 
			
		||||
@@ -0,0 +1,29 @@
 | 
			
		||||
# Generated by Django 3.2 on 2021-11-14 15:24
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('parts', '0005_auto_20211113_1912'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name='component',
 | 
			
		||||
            name='manufacturer',
 | 
			
		||||
            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='parts.manufacturer'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name='component',
 | 
			
		||||
            name='package',
 | 
			
		||||
            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='parts.package'),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name='component',
 | 
			
		||||
            name='pref_distri',
 | 
			
		||||
            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='parts.distributor'),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -157,12 +157,12 @@ class Component(models.Model):
 | 
			
		||||
 | 
			
		||||
	id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
 | 
			
		||||
	name = models.CharField(max_length=100)
 | 
			
		||||
	manufacturer = models.ForeignKey(Manufacturer, on_delete=models.SET_NULL, blank=True, null=True)
 | 
			
		||||
	manufacturer = models.ForeignKey(Manufacturer, on_delete=models.PROTECT, blank=True, null=True)
 | 
			
		||||
	component_type = models.ForeignKey(ComponentType, on_delete=models.SET_NULL, blank=True, null=True)
 | 
			
		||||
	pref_distri = models.ForeignKey(Distributor, on_delete=models.SET_NULL, blank=True, null=True)
 | 
			
		||||
	pref_distri = models.ForeignKey(Distributor, on_delete=models.PROTECT, blank=True, null=True)
 | 
			
		||||
	description = models.TextField(null=True, blank=True)
 | 
			
		||||
	datasheet_link = models.CharField(max_length=300, null=True, blank=True)
 | 
			
		||||
	package = models.ForeignKey(Package, on_delete=models.SET_NULL, blank=True, null=True)
 | 
			
		||||
	package = models.ForeignKey(Package, on_delete=models.PROTECT, blank=True, null=True)
 | 
			
		||||
	image = models.ImageField(upload_to=RandomFileName.RandomFileName('component-images'), blank=True, null=True)
 | 
			
		||||
 | 
			
		||||
	def __str__(self):
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,8 @@ from .qr_parser import QrCodeValidator
 | 
			
		||||
from django.core.paginator import Paginator
 | 
			
		||||
from django.core.exceptions import ValidationError
 | 
			
		||||
from django.db import IntegrityError
 | 
			
		||||
from .forms import MyTestForm, AddSubStorageForm, DeleteStockForm, EditWatermarkForm, EditStockAmountForm, AddStockForm, EditComponentForm, EditComponentParameterForm, DistributorNumberForm, DistributorNumberFormSet
 | 
			
		||||
from django.db.models import ProtectedError
 | 
			
		||||
from .forms import *
 | 
			
		||||
from django.db.models import Q
 | 
			
		||||
from django.db.models.functions import Lower
 | 
			
		||||
import uuid
 | 
			
		||||
@@ -527,5 +528,48 @@ class PackageDetailView(LoginRequiredMixin, BaseTemplateMixin, DetailView):
 | 
			
		||||
        self.base_title = 'Package / '+self.object.name
 | 
			
		||||
        context = super().get_context_data(**kwargs)
 | 
			
		||||
        context['package'] = self.object
 | 
			
		||||
        context['edit_form'] = PackageForm(instance=self.object)
 | 
			
		||||
 
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
    def handle_delete_package(self, request):
 | 
			
		||||
        delete_error = None
 | 
			
		||||
        protected_objects = None
 | 
			
		||||
        
 | 
			
		||||
        # Try to delete this instance
 | 
			
		||||
        try:
 | 
			
		||||
            self.object.delete()
 | 
			
		||||
        except ProtectedError as pe:
 | 
			
		||||
            delete_error = 'Cannot delete this package. It is referenced by a component.'
 | 
			
		||||
            protected_objects = pe.protected_objects
 | 
			
		||||
        except:
 | 
			
		||||
            delete_error = 'Cannot delete this package. Unknown error'
 | 
			
		||||
        
 | 
			
		||||
        if delete_error:
 | 
			
		||||
            context = self.get_context_data()
 | 
			
		||||
            context['delete_error'] = delete_error
 | 
			
		||||
            context['protected_components'] = protected_objects
 | 
			
		||||
            return self.render_to_response(context)
 | 
			
		||||
        else:
 | 
			
		||||
            return redirect('parts-main')
 | 
			
		||||
 | 
			
		||||
    def edit_package(self, request):
 | 
			
		||||
        edit_form = PackageForm(data=request.POST, files=request.FILES, instance=self.object)
 | 
			
		||||
 | 
			
		||||
        if edit_form.is_valid():
 | 
			
		||||
            edit_form.save()
 | 
			
		||||
 | 
			
		||||
        context = self.get_context_data()
 | 
			
		||||
        if not edit_form.is_valid():
 | 
			
		||||
            context['edit_form'] = edit_form
 | 
			
		||||
        return self.render_to_response(context)
 | 
			
		||||
 | 
			
		||||
    def post(self, request, *args, **kwargs):
 | 
			
		||||
        self.object = self.get_object()
 | 
			
		||||
 | 
			
		||||
        if 'submit-pkg-delete' in request.POST:
 | 
			
		||||
            return self.handle_delete_package(request)
 | 
			
		||||
        elif 'submit-pkg-edit' in request.POST:
 | 
			
		||||
            return self.edit_package(request)
 | 
			
		||||
        
 | 
			
		||||
        return super().post(request, *args, **kwargs)
 | 
			
		||||
@@ -1,8 +1,94 @@
 | 
			
		||||
{% extends 'base.html' %}
 | 
			
		||||
 | 
			
		||||
{% load static %}
 | 
			
		||||
{% load crispy_forms_tags %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
<div class="container">
 | 
			
		||||
    Meow<br>
 | 
			
		||||
    {{package}}
 | 
			
		||||
    <div class="row">
 | 
			
		||||
        <div class="col-md-3">
 | 
			
		||||
            <div class="row justify-content-center">
 | 
			
		||||
                {% if package.image %}
 | 
			
		||||
                    <img src="{{package.image.url}}" alt="{{package.name}}" class="component-img-big btn" data-bs-toggle="modal" data-bs-target="#pkg-img-modal">
 | 
			
		||||
                {% else %}
 | 
			
		||||
                    <img src="{% static 'css/icons/card-image.svg' %}" alt="{{package.name}}" class="component-img-def-big">
 | 
			
		||||
                {% endif %}
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row">
 | 
			
		||||
                <button class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#pkg-delete-modal"><i class="bi bi-file-x"></i> Delete {{package.name}}</button>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="col m-1">
 | 
			
		||||
        <h2>Package {{package.name}}</h2>
 | 
			
		||||
        <form action="" method="post" enctype="multipart/form-data">
 | 
			
		||||
            {% csrf_token %}
 | 
			
		||||
            {{edit_form|crispy}}
 | 
			
		||||
            <input type="submit" class="btn btn-primary" value="Save" name="submit-pkg-edit">
 | 
			
		||||
        </form>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
{% if package.image %}
 | 
			
		||||
<div class="modal fade" id="pkg-img-modal" tabindex="-1">
 | 
			
		||||
    <div class="modal-dialog modal-lg modal-fullscreen-lg-down">
 | 
			
		||||
        <div class="modal-content">
 | 
			
		||||
            <div class="modal-header">
 | 
			
		||||
                <h5>{{package.name}}</h5>
 | 
			
		||||
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="modal-body">
 | 
			
		||||
                <div class="text-center">
 | 
			
		||||
                    <img class="component-img-huge" src="{{package.image.url}}">
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endif %}
 | 
			
		||||
 | 
			
		||||
<!-- Delete modal -->
 | 
			
		||||
<div class="modal fade" id="pkg-delete-modal" tabindex="-1">
 | 
			
		||||
    <div class="modal-dialog modal-lg modal-fullscreen-lg-down">
 | 
			
		||||
        <div class="modal-content">
 | 
			
		||||
            <div class="modal-header">
 | 
			
		||||
                <h5>{{package.name}}</h5>
 | 
			
		||||
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="modal-body">
 | 
			
		||||
                <h4>Delete this package?</h4>
 | 
			
		||||
                {% if delete_error %}
 | 
			
		||||
                <div class="alert alert-danger">
 | 
			
		||||
                    {{delete_error}}
 | 
			
		||||
                </div>
 | 
			
		||||
                {% if protected_components %}
 | 
			
		||||
                <h4>Following components prevent the deletion:</h4>
 | 
			
		||||
                <ul>
 | 
			
		||||
                    {% for comp in protected_components %}
 | 
			
		||||
                    <li><a class="text-decoration-none text-primary" href="{% url 'parts-components-detail' uuid=comp.id %}">{{comp}}</a></li>
 | 
			
		||||
                    {% endfor %}
 | 
			
		||||
                </ul>
 | 
			
		||||
                {% endif %}
 | 
			
		||||
                {% endif %}
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="modal-footer">
 | 
			
		||||
                <form action="" method="post">
 | 
			
		||||
                    {% csrf_token %}
 | 
			
		||||
                    <button type="submit" class="btn btn-danger" name="submit-pkg-delete"><i class="bi bi-file-x"></i> Delete {{package.name}}</button>
 | 
			
		||||
                </form>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% endblock content %}
 | 
			
		||||
 | 
			
		||||
{% block custom_scripts %}
 | 
			
		||||
<script type="text/javascript">
 | 
			
		||||
{% if delete_error %}
 | 
			
		||||
bootstrap.Modal.getOrCreateInstance(document.getElementById('pkg-delete-modal')).show();
 | 
			
		||||
{% endif %}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{% endblock custom_scripts %}
 | 
			
		||||
		Reference in New Issue
	
	Block a user