Compare commits
6 Commits
ea623212bb
...
master
Author | SHA1 | Date | |
---|---|---|---|
6dd781021c | |||
7e0fc86b7f | |||
7a1bf054f5 | |||
5b6f4e16ef | |||
191705c6a6 | |||
ba0da19810 |
1
.dockerignore
Normal file
1
.dockerignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
start_server.sh
|
6
Dockerfile
Normal file
6
Dockerfile
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
FROM alpine:latest
|
||||||
|
RUN apk add --no-cache python3 py3-pip python3-dev py3-setuptools gcc python3-dev jpeg-dev zlib-dev musl-dev py3-gunicorn
|
||||||
|
COPY . /home/shimatta/kenkyusho
|
||||||
|
WORKDIR /home/shimatta/kenkyusho
|
||||||
|
RUN python3 -m venv /home/shimatta/kenkyusho/.venv && . /home/shimatta/kenkyusho/.venv/bin/activate && pip install -r requirements.txt
|
||||||
|
ENTRYPOINT ["/home/shimatta/kenkyusho/entrypoint.sh"]
|
6
entrypoint.sh
Executable file
6
entrypoint.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
source /home/shimatta/kenkyusho/.venv/bin/activate
|
||||||
|
cd /home/shimatta/kenkyusho/shimatta_kenkyusho
|
||||||
|
python manage.py migrate --settings shimatta_kenkyusho.settings_production
|
||||||
|
python manage.py collectstatic --settings shimatta_kenkyusho.settings_production --noinput
|
||||||
|
gunicorn -w 4 shimatta_kenkyusho.wsgi:application
|
@@ -14,7 +14,6 @@ lazy-object-proxy==1.6.0
|
|||||||
MarkupSafe==2.0.1
|
MarkupSafe==2.0.1
|
||||||
mccabe==0.6.1
|
mccabe==0.6.1
|
||||||
Pillow==8.3.1
|
Pillow==8.3.1
|
||||||
psycopg2==2.9.1
|
|
||||||
pylint==2.9.6
|
pylint==2.9.6
|
||||||
pytz==2021.1
|
pytz==2021.1
|
||||||
qrcode==7.2
|
qrcode==7.2
|
||||||
@@ -23,3 +22,5 @@ six==1.16.0
|
|||||||
sqlparse==0.4.1
|
sqlparse==0.4.1
|
||||||
toml==0.10.2
|
toml==0.10.2
|
||||||
wrapt==1.12.1
|
wrapt==1.12.1
|
||||||
|
psycopg2-binary==2.9.9
|
||||||
|
gunicorn==21.2.0
|
||||||
|
@@ -9,7 +9,6 @@ admin.site.register(parts_models.Manufacturer)
|
|||||||
admin.site.register(parts_models.Storage)
|
admin.site.register(parts_models.Storage)
|
||||||
admin.site.register(parts_models.Stock)
|
admin.site.register(parts_models.Stock)
|
||||||
admin.site.register(parts_models.ComponentParameter)
|
admin.site.register(parts_models.ComponentParameter)
|
||||||
admin.site.register(parts_models.PackageParameter)
|
|
||||||
admin.site.register(parts_models.ComponentParameterType)
|
admin.site.register(parts_models.ComponentParameterType)
|
||||||
admin.site.register(parts_models.ComponentType)
|
admin.site.register(parts_models.ComponentType)
|
||||||
admin.site.register(parts_models.Distributor)
|
admin.site.register(parts_models.Distributor)
|
||||||
|
@@ -244,7 +244,6 @@ class AdvancedComponentSearchForm(forms.Form):
|
|||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.helper = FormHelper()
|
self.helper = FormHelper()
|
||||||
self.helper.form_tag = False
|
self.helper.form_tag = False
|
||||||
self.helper.disable_csrf = True
|
|
||||||
self.helper.layout = Layout(
|
self.helper.layout = Layout(
|
||||||
Row(
|
Row(
|
||||||
Column('name'),
|
Column('name'),
|
||||||
@@ -263,53 +262,20 @@ class AdvancedComponentSearchForm(forms.Form):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
PARAMETER_COMPARISON_TYPES = (
|
|
||||||
('eq', '=='),
|
|
||||||
('lte', '<='),
|
|
||||||
('gte', '>='),
|
|
||||||
)
|
|
||||||
|
|
||||||
class ComponentParameterSearchForm(forms.Form):
|
class ComponentParameterSearchForm(forms.Form):
|
||||||
parameter = AutocompleteForeingKeyField(required=True, foreign_model=parts_models.ComponentParameterType, api_search_url='componentparametertype-list', image_field_name=None, name_field_name='parameter_name')
|
parameter = AutocompleteForeingKeyField(required=True, foreign_model=parts_models.ComponentParameterType, api_search_url='componentparametertype-list', image_field_name=None, name_field_name='parameter_name')
|
||||||
value = forms.CharField(max_length=100, required=False)
|
value = forms.CharField(max_length=100, required=False)
|
||||||
compare_method = forms.ChoiceField(choices=PARAMETER_COMPARISON_TYPES, required=True, initial=1)
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.helper = FormHelper()
|
self.helper = FormHelper()
|
||||||
self.helper.form_tag = False
|
self.helper.form_tag = False
|
||||||
self.helper.disable_csrf = True
|
|
||||||
self.helper.layout = Layout(
|
self.helper.layout = Layout(
|
||||||
Row(
|
Row(
|
||||||
Column('parameter'),
|
Column('parameter'),
|
||||||
Column('compare_method'),
|
|
||||||
Column('value')
|
Column('value')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
cleaned_data = super().clean()
|
|
||||||
parameter = cleaned_data.get('parameter')
|
|
||||||
value = cleaned_data.get('value')
|
|
||||||
|
|
||||||
if value != '' or value != None:
|
|
||||||
value = value.strip()
|
|
||||||
|
|
||||||
if value == '' or value == None:
|
|
||||||
cleaned_data['value'] = None
|
|
||||||
value = None
|
|
||||||
|
|
||||||
if parameter and value is not None and value != '':
|
|
||||||
if parameter.parameter_type != 'F':
|
|
||||||
try:
|
|
||||||
cleaned_data['value'] = EngineeringNumberConverter.engineering_to_number(value)
|
|
||||||
except:
|
|
||||||
raise ValidationError('Cannot convert value to number')
|
|
||||||
|
|
||||||
return cleaned_data
|
|
||||||
|
|
||||||
|
|
||||||
class ComponentParameterCreateForm(forms.Form):
|
class ComponentParameterCreateForm(forms.Form):
|
||||||
parameter_type = AutocompleteForeingKeyField(required=True, foreign_model=parts_models.ComponentParameterType, api_search_url='componentparametertype-list', image_field_name=None, name_field_name='descriptive_name')
|
parameter_type = AutocompleteForeingKeyField(required=True, foreign_model=parts_models.ComponentParameterType, api_search_url='componentparametertype-list', image_field_name=None, name_field_name='descriptive_name')
|
||||||
value = forms.CharField(required=True, max_length=256)
|
value = forms.CharField(required=True, max_length=256)
|
||||||
|
@@ -0,0 +1,59 @@
|
|||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from parts.models import Component, Package, Distributor, Manufacturer
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Migrate all media files to the current folder structure'
|
||||||
|
|
||||||
|
def move_files_of_model(self, queryset):
|
||||||
|
for comp in queryset:
|
||||||
|
img_path = comp.image.name
|
||||||
|
img_path = os.path.normpath(img_path)
|
||||||
|
path_components = img_path.split(os.sep)
|
||||||
|
|
||||||
|
if len(path_components) <= 2:
|
||||||
|
self.stdout.write(f'Legacy path found: {img_path}. Will be moved')
|
||||||
|
full_path_components = os.path.normpath(comp.image.path).split(os.sep)
|
||||||
|
fname = full_path_components[-1]
|
||||||
|
path_elem_count = len(full_path_components)
|
||||||
|
full_path_components.insert(path_elem_count-1, str(fname[1]))
|
||||||
|
full_path_components.insert(path_elem_count-1, str(fname[0]))
|
||||||
|
dest_path = os.sep.join(full_path_components)
|
||||||
|
|
||||||
|
# Move file
|
||||||
|
os.makedirs(os.path.dirname(dest_path), exist_ok=True)
|
||||||
|
shutil.move(comp.image.path, dest_path)
|
||||||
|
|
||||||
|
# Update model
|
||||||
|
new_rel_path_comps = path_components
|
||||||
|
l = len(new_rel_path_comps)
|
||||||
|
new_rel_path_comps.insert(l-1, str(fname[1]))
|
||||||
|
new_rel_path_comps.insert(l-1, str(fname[0]))
|
||||||
|
new_name = os.sep.join(new_rel_path_comps)
|
||||||
|
self.stdout.write(f'New location: {dest_path}, new name: {new_name}')
|
||||||
|
comp.image.name = new_name
|
||||||
|
comp.save()
|
||||||
|
|
||||||
|
def handle(self, *args, **kwargs):
|
||||||
|
|
||||||
|
self.stdout.write('Querying components...')
|
||||||
|
components = Component.objects.exclude(image='')
|
||||||
|
self.stdout.write(f'Count of components with images: {components.count()}');
|
||||||
|
self.move_files_of_model(components)
|
||||||
|
|
||||||
|
self.stdout.write('Querying packages...')
|
||||||
|
pkgs = Package.objects.exclude(image='')
|
||||||
|
self.stdout.write(f'Count of components with images: {pkgs.count()}');
|
||||||
|
self.move_files_of_model(pkgs)
|
||||||
|
|
||||||
|
self.stdout.write('Querying manufacturers...')
|
||||||
|
manufacturers = Manufacturer.objects.exclude(image='')
|
||||||
|
self.stdout.write(f'Count of components with images: {manufacturers.count()}');
|
||||||
|
self.move_files_of_model(manufacturers)
|
||||||
|
|
||||||
|
self.stdout.write('Querying distributors...')
|
||||||
|
distris = Distributor.objects.exclude(image='')
|
||||||
|
self.stdout.write(f'Count of components with images: {distris.count()}');
|
||||||
|
self.move_files_of_model(distris)
|
||||||
|
|
@@ -1,44 +0,0 @@
|
|||||||
# Generated by Django 3.2.5 on 2022-01-10 18:12
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('parts', '0010_auto_20220103_1606'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='componenttype',
|
|
||||||
name='key_parameter1',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='type_param1', to='parts.componentparametertype'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='componenttype',
|
|
||||||
name='key_parameter2',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='type_param2', to='parts.componentparametertype'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='componenttype',
|
|
||||||
name='key_parameter3',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='type_param3', to='parts.componentparametertype'),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='PackageParameter',
|
|
||||||
fields=[
|
|
||||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
|
||||||
('value', models.FloatField(default=0)),
|
|
||||||
('text_value', models.TextField(blank=True)),
|
|
||||||
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='parts.package')),
|
|
||||||
('parameter_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='parts.componentparametertype')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'ordering': ['id'],
|
|
||||||
'unique_together': {('package', 'parameter_type')},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
@@ -49,10 +49,7 @@ class ComponentType(models.Model):
|
|||||||
class_name = models.CharField(max_length=50, unique=True)
|
class_name = models.CharField(max_length=50, unique=True)
|
||||||
passive = models.BooleanField()
|
passive = models.BooleanField()
|
||||||
possible_parameter = models.ManyToManyField(ComponentParameterType, blank=True)
|
possible_parameter = models.ManyToManyField(ComponentParameterType, blank=True)
|
||||||
key_parameter1 = models.ForeignKey(ComponentParameterType, on_delete=models.CASCADE, blank=True, null=True, related_name="type_param1")
|
|
||||||
key_parameter2 = models.ForeignKey(ComponentParameterType, on_delete=models.CASCADE, blank=True, null=True, related_name="type_param2")
|
|
||||||
key_parameter3 = models.ForeignKey(ComponentParameterType, on_delete=models.CASCADE, blank=True, null=True, related_name="type_param3")
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '[' + self.class_name + ']'
|
return '[' + self.class_name + ']'
|
||||||
|
|
||||||
@@ -147,37 +144,6 @@ class Package(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class PackageParameter(models.Model):
|
|
||||||
class Meta:
|
|
||||||
unique_together = ('package', 'parameter_type')
|
|
||||||
ordering = ['id']
|
|
||||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
|
|
||||||
package = models.ForeignKey(Package, on_delete=models.CASCADE) # A target package is required!
|
|
||||||
parameter_type = models.ForeignKey(ComponentParameterType, on_delete=models.CASCADE)
|
|
||||||
value = models.FloatField(default=0)
|
|
||||||
text_value = models.TextField(null=False, blank=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
if self.parameter_type.parameter_type == 'F':
|
|
||||||
value = self.text_value
|
|
||||||
else:
|
|
||||||
value = str(self.value)
|
|
||||||
|
|
||||||
return str(self.package)+ ': '+ str(self.parameter_type) + ': ' + value
|
|
||||||
|
|
||||||
def resolved_value_as_string(self):
|
|
||||||
my_type = self.parameter_type.parameter_type
|
|
||||||
|
|
||||||
if my_type == 'E' or my_type == 'I':
|
|
||||||
# Engineering float number
|
|
||||||
(num, prefix) = NumConv.number_to_engineering(self.value, it_unit=(True if my_type=='I' else False))
|
|
||||||
return f'{num:.3f} {prefix}{self.parameter_type.unit}'
|
|
||||||
elif my_type == 'N':
|
|
||||||
# Standard float number
|
|
||||||
return f'{self.value:.3f} {self.parameter_type.unit}'
|
|
||||||
elif my_type == 'F':
|
|
||||||
return self.text_value
|
|
||||||
|
|
||||||
|
|
||||||
class Manufacturer(models.Model):
|
class Manufacturer(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@@ -11,7 +11,7 @@ from django.views import View
|
|||||||
import django.forms as forms
|
import django.forms as forms
|
||||||
from django.views.generic import TemplateView, DetailView
|
from django.views.generic import TemplateView, DetailView
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
||||||
from .models import Storage, Stock, Component, Distributor, Manufacturer, Package, ComponentParameter, ComponentParameterType, DistributorNum, PackageParameter
|
from .models import Storage, Stock, Component, Distributor, Manufacturer, Package, ComponentParameter, ComponentParameterType, DistributorNum
|
||||||
from .qr_parser import QrCodeValidator
|
from .qr_parser import QrCodeValidator
|
||||||
from django.core.paginator import Paginator
|
from django.core.paginator import Paginator
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
@@ -23,7 +23,7 @@ from django.db.models.functions import Lower
|
|||||||
from django.forms import formset_factory
|
from django.forms import formset_factory
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
ParameterSearchFormSet = formset_factory(ComponentParameterSearchForm, extra=0)
|
ParameterSearchFormSet = formset_factory(ComponentParameterSearchForm, extra=1)
|
||||||
|
|
||||||
class QrSearchForm(forms.Form):
|
class QrSearchForm(forms.Form):
|
||||||
my_qr_validator = QrCodeValidator()
|
my_qr_validator = QrCodeValidator()
|
||||||
@@ -149,9 +149,9 @@ class ComponentView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
|
|||||||
default_page_size = 25
|
default_page_size = 25
|
||||||
|
|
||||||
def get_component_query_set(self, search_string):
|
def get_component_query_set(self, search_string):
|
||||||
queryset = Component.objects.select_related('package', 'manufacturer').all()
|
queryset = Component.objects.all()
|
||||||
|
|
||||||
if search_string is None or search_string == '':
|
if not search_string:
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
search_fragments = search_string.strip().split()
|
search_fragments = search_string.strip().split()
|
||||||
@@ -161,7 +161,7 @@ class ComponentView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
|
|||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def get_component_queryset_from_advanced_search(self, cleaned_data):
|
def get_component_queryset_from_advanced_search(self, cleaned_data):
|
||||||
queryset = Component.objects.select_related('manufacturer', 'package').all()
|
queryset = Component.objects.all()
|
||||||
|
|
||||||
if cleaned_data['name']:
|
if cleaned_data['name']:
|
||||||
queryset = queryset.filter(Q(name__icontains=cleaned_data['name']))
|
queryset = queryset.filter(Q(name__icontains=cleaned_data['name']))
|
||||||
@@ -181,21 +181,6 @@ class ComponentView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
|
|||||||
queryset = queryset.filter(manufacturer=cleaned_data['manufacturer'])
|
queryset = queryset.filter(manufacturer=cleaned_data['manufacturer'])
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def filter_queryset_with_parameters(self, queryset, parameter, value, compare_method):
|
|
||||||
if parameter and (value is None or value == ''):
|
|
||||||
return queryset.filter(Q(componentparameter__parameter_type=parameter))
|
|
||||||
elif parameter and value is not None:
|
|
||||||
if parameter.parameter_type == 'F':
|
|
||||||
return queryset.filter(Q(componentparameter__text_value__icontains=value) & Q(componentparameter__parameter_type=parameter))
|
|
||||||
else:
|
|
||||||
if compare_method == 'lte': # <=
|
|
||||||
return queryset.filter(Q(componentparameter__value__lte=value) & Q(componentparameter__parameter_type=parameter))
|
|
||||||
elif compare_method == 'gte': # >=
|
|
||||||
return queryset.filter(Q(componentparameter__value__gte=value) & Q(componentparameter__parameter_type=parameter))
|
|
||||||
else:
|
|
||||||
return queryset.filter(Q(componentparameter__value=value) & Q(componentparameter__parameter_type=parameter))
|
|
||||||
return queryset
|
|
||||||
|
|
||||||
def get_context_data_int(self, advanced_search, parameter_formset : ParameterSearchFormSet, **kwargs):
|
def get_context_data_int(self, advanced_search, parameter_formset : ParameterSearchFormSet, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
@@ -209,14 +194,11 @@ class ComponentView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
|
|||||||
if advanced_search.is_valid():
|
if advanced_search.is_valid():
|
||||||
paginator_queryset = self.get_component_queryset_from_advanced_search(advanced_search.cleaned_data)
|
paginator_queryset = self.get_component_queryset_from_advanced_search(advanced_search.cleaned_data)
|
||||||
else:
|
else:
|
||||||
paginator_queryset = self.get_component_query_set(None)
|
paginator_queryset = Component.objects.all()
|
||||||
|
|
||||||
# Process parameters
|
if parameter_formset.is_valid():
|
||||||
for f in parameter_formset:
|
# Process parameters
|
||||||
# If the form is valid and has changed compared to its initial empty state
|
pass
|
||||||
if f.is_valid() and f.has_changed():
|
|
||||||
paginator_queryset = self.filter_queryset_with_parameters(paginator_queryset, f.cleaned_data['parameter'], f.cleaned_data['value'], f.cleaned_data['compare_method'])
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
search = self.request.GET.get('search', default=None)
|
search = self.request.GET.get('search', default=None)
|
||||||
@@ -230,24 +212,15 @@ class ComponentView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
|
|||||||
|
|
||||||
if not parameter_formset:
|
if not parameter_formset:
|
||||||
context['advanced_search_param_formset'] = ParameterSearchFormSet()
|
context['advanced_search_param_formset'] = ParameterSearchFormSet()
|
||||||
|
|
||||||
|
|
||||||
if not advanced_search:
|
if not advanced_search:
|
||||||
context['advanced_search_form'] = AdvancedComponentSearchForm(auto_id='adv_search_%s')
|
context['advanced_search_form'] = AdvancedComponentSearchForm(auto_id='adv_search_%s')
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
adv_search_form = None
|
return self.get_context_data_int(advanced_search = None, parameter_formset=None, **kwargs)
|
||||||
adv_param_search_formset = None
|
|
||||||
if 'submit-advanced-search' in self.request.GET:
|
|
||||||
adv_search_form = AdvancedComponentSearchForm(auto_id='adv_search_%s', data=self.request.GET)
|
|
||||||
adv_param_search_formset = ParameterSearchFormSet(data=self.request.GET)
|
|
||||||
if adv_search_form.is_valid():
|
|
||||||
pass
|
|
||||||
if adv_param_search_formset.is_valid():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
return self.get_context_data_int(advanced_search = adv_search_form, parameter_formset=adv_param_search_formset, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_new_component_post(self, request, open=False, **kwargs):
|
def handle_new_component_post(self, request, open=False, **kwargs):
|
||||||
@@ -263,12 +236,29 @@ class ComponentView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
|
|||||||
if open and new_component:
|
if open and new_component:
|
||||||
return redirect(reverse('parts-components-detail', kwargs={'uuid':new_component.id}))
|
return redirect(reverse('parts-components-detail', kwargs={'uuid':new_component.id}))
|
||||||
return self.render_to_response(context)
|
return self.render_to_response(context)
|
||||||
|
|
||||||
|
def handle_advanced_search_post(self, request, **kwargs):
|
||||||
|
|
||||||
|
form = AdvancedComponentSearchForm(auto_id='adv_search_%s', data=request.POST)
|
||||||
|
param_formset = ParameterSearchFormSet(data=request.POST)
|
||||||
|
|
||||||
|
if form.is_valid():
|
||||||
|
print('Valid')
|
||||||
|
|
||||||
|
if param_formset.is_valid():
|
||||||
|
print('Formset is valid!')
|
||||||
|
|
||||||
|
|
||||||
|
context = self.get_context_data_int(form, param_formset, **kwargs)
|
||||||
|
return self.render_to_response(context)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
if 'submit-edit-component' in request.POST:
|
if 'submit-edit-component' in request.POST:
|
||||||
return self.handle_new_component_post(request, open=False, **kwargs)
|
return self.handle_new_component_post(request, open=False, **kwargs)
|
||||||
elif 'submit-edit-component-open' in request.POST:
|
elif 'submit-edit-component-open' in request.POST:
|
||||||
return self.handle_new_component_post(request, open=True, **kwargs)
|
return self.handle_new_component_post(request, open=True, **kwargs)
|
||||||
|
elif 'submit-advanced-search' in request.POST:
|
||||||
|
return self.handle_advanced_search_post(request, **kwargs)
|
||||||
else:
|
else:
|
||||||
return super().post(request, *args, **kwargs)
|
return super().post(request, *args, **kwargs)
|
||||||
|
|
||||||
@@ -567,10 +557,9 @@ class StockViewDetail(LoginRequiredMixin, BaseTemplateMixin, DetailView):
|
|||||||
if edit_form.is_valid():
|
if edit_form.is_valid():
|
||||||
edit_form.save()
|
edit_form.save()
|
||||||
else:
|
else:
|
||||||
pass
|
pass # Todo: Handle error
|
||||||
|
|
||||||
context = self.get_context_data(**kwargs)
|
context = self.get_context_data(**kwargs)
|
||||||
|
|
||||||
return self.render_to_response(context)
|
return self.render_to_response(context)
|
||||||
|
|
||||||
def handle_amount_change_post(self, request, increase, **kwargs):
|
def handle_amount_change_post(self, request, increase, **kwargs):
|
||||||
@@ -636,9 +625,7 @@ class ComponentDetailView(LoginRequiredMixin, BaseTemplateMixin, DetailView):
|
|||||||
context['new_param_form'] = ComponentParameterCreateForm()
|
context['new_param_form'] = ComponentParameterCreateForm()
|
||||||
context['distri_nums'] = DistributorNum.objects.filter(component=self.object).order_by('distributor__name')
|
context['distri_nums'] = DistributorNum.objects.filter(component=self.object).order_by('distributor__name')
|
||||||
context['parameters'] = ComponentParameter.objects.filter(component=self.object).order_by('parameter_type__parameter_name')
|
context['parameters'] = ComponentParameter.objects.filter(component=self.object).order_by('parameter_type__parameter_name')
|
||||||
if self.object.package:
|
|
||||||
context['package_parameters'] = PackageParameter.objects.filter(package=self.object.package).order_by('parameter_type__parameter_name')
|
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def handle_submit_edit_component_post(self, request, **kwargs):
|
def handle_submit_edit_component_post(self, request, **kwargs):
|
||||||
|
@@ -138,6 +138,7 @@ DATABASES = {
|
|||||||
'USER': db_user,
|
'USER': db_user,
|
||||||
'PASSWORD': db_pw,
|
'PASSWORD': db_pw,
|
||||||
'HOST': get_env_value('DJANGO_POSTGRESQL_SOCKET'),
|
'HOST': get_env_value('DJANGO_POSTGRESQL_SOCKET'),
|
||||||
|
'PORT': get_env_value('DJANGO_POSTGRESQL_PORT'),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,6 +230,6 @@ CRISPY_TEMPLATE_PACK = "bootstrap5"
|
|||||||
SESSION_COOKIE_SECURE = True
|
SESSION_COOKIE_SECURE = True
|
||||||
CSRF_COOKIE_SECURE = True
|
CSRF_COOKIE_SECURE = True
|
||||||
|
|
||||||
SECURE_SSL_REDIRECT = True
|
SECURE_SSL_REDIRECT = False
|
||||||
|
|
||||||
SECURE_HSTS_SECONDS = get_env_value('DJANGO_SECURE_HSTS_SECONDS', default=120)
|
SECURE_HSTS_SECONDS = get_env_value('DJANGO_SECURE_HSTS_SECONDS', default=120)
|
@@ -6,8 +6,13 @@ from django.utils.deconstruct import deconstructible
|
|||||||
@deconstructible
|
@deconstructible
|
||||||
class RandomFileName(object):
|
class RandomFileName(object):
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
self.path = os.path.join(path, "%s%s")
|
self.path = os.path.join(path, "%s/%s/%s%s")
|
||||||
|
|
||||||
def __call__(self, _, filename):
|
def __call__(self, _, filename):
|
||||||
extension = os.path.splitext(filename)[1]
|
extension = os.path.splitext(filename)[1]
|
||||||
return self.path % (uuid.uuid4(), extension)
|
file_uuid = uuid.uuid4()
|
||||||
|
uuid_str = str(file_uuid)
|
||||||
|
first_char = uuid_str[0]
|
||||||
|
second_char = uuid_str[1]
|
||||||
|
|
||||||
|
return self.path % (first_char, second_char, file_uuid, extension)
|
||||||
|
@@ -119,17 +119,6 @@
|
|||||||
<th scope="col"></th>
|
<th scope="col"></th>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for param in package_parameters %}
|
|
||||||
<td>
|
|
||||||
<h6 {% if param.parameter_type.parameter_description %} class="accordion-header" data-bs-toggle="collapse" data-bs-target="#collapse-pkg-parameter-desc-{{forloop.counter}}"{% endif %}>
|
|
||||||
{{param.parameter_type.parameter_name}}
|
|
||||||
</h6>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{param.resolved_value_as_string}}
|
|
||||||
</td>
|
|
||||||
<td><span class="text-info">from Package</span></td>
|
|
||||||
{% endfor %}
|
|
||||||
{% for param in parameters %}
|
{% for param in parameters %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
@@ -159,13 +148,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for param in package_parameters %}
|
|
||||||
{% if param.parameter_type.parameter_description %}
|
|
||||||
<div class="collapse accordion-collapse" id="collapse-pkg-parameter-desc-{{forloop.counter}}" data-bs-parent="#accordion-param-desc">
|
|
||||||
{{param.parameter_type.parameter_description}}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div class="collapse mb-3{% if advanced_search_shown %} show{% endif %}" id="advanced-search-collapse" aria-expanded="{% if advanced_search_shown %}true{% else %}false{% endif %}">
|
<div class="collapse mb-3{% if advanced_search_shown %} show{% endif %}" id="advanced-search-collapse" aria-expanded="{% if advanced_search_shown %}true{% else %}false{% endif %}">
|
||||||
<form method="GET">
|
<form method="POST">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
{% crispy advanced_search_form %}
|
{% crispy advanced_search_form %}
|
||||||
@@ -31,9 +31,6 @@
|
|||||||
<input type="submit" name="submit-advanced-search" value="Search" class="btn btn-success">
|
<input type="submit" name="submit-advanced-search" value="Search" class="btn btn-success">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<template id="advanced-search-parameter-template">
|
|
||||||
{% crispy advanced_search_param_formset.empty_form %}
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="list-group mb-3">
|
<div class="list-group mb-3">
|
||||||
{% for comp in components %}
|
{% for comp in components %}
|
||||||
|
1
start_server.sh
Executable file
1
start_server.sh
Executable file
@@ -0,0 +1 @@
|
|||||||
|
podman run -it -e DJANGO_SECRET_KEY=<secret_key> -e DJANGO_ALLOWED_HOST=parts.shimatta.net -e DJANGO_STATIC_ROOT=/var/static -e DJANGO_MEDIA_URL=media -e DJANGO_MEDIA_ROOT=/var/media -e DJANGO_POSTGRESQL_SOCKET=host.docker.internal -e DJANGO_POSTGRESQL_PORT=2345 -e DJANGO_POSTGRESQL_USER=<db_user> -e DJANGO_POSTGRESQL_PW=<db_pass> -v /var/parts/static:/var/static -v /var/parts/media:/var/media -p 8000:8000 --entrypoint /bin/sh localhost/kenkyusho:0.1
|
Reference in New Issue
Block a user