fix lot properties and clean absurd code from chatgpt

This commit is contained in:
Cayo Puigdefabregas 2025-01-31 13:39:03 +01:00
parent f88e9b144e
commit a70e6eaf0d
8 changed files with 128 additions and 115 deletions

View file

@ -82,7 +82,7 @@
<div class="modal-footer justify-content-center"> <div class="modal-footer justify-content-center">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans "Cancel" %} <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans "Cancel" %}
</button> </button>
<form method="post" action="{% url 'device:delete_user_property' a.id %}"> <form method="post" action="{% url 'device:delete_user_property' object.id a.id %}">
{% csrf_token %} {% csrf_token %}
<button type="submit" class="btn btn-danger">{% trans "Delete" %} <button type="submit" class="btn btn-danger">{% trans "Delete" %}
</button> </button>
@ -105,7 +105,7 @@
</button> </button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form id="editForm{{ a.id }}" method="post" action="{% url 'device:update_user_property' a.id %}"> <form id="editForm{{ a.id }}" method="post" action="{% url 'device:update_user_property' object.id a.id %}">
{% csrf_token %} {% csrf_token %}
<div class="mb-3"> <div class="mb-3">
<label for="key" class="form-label">{% trans "Key" %} <label for="key" class="form-label">{% trans "Key" %}

View file

@ -7,8 +7,11 @@ urlpatterns = [
path("add/", views.NewDeviceView.as_view(), name="add"), path("add/", views.NewDeviceView.as_view(), name="add"),
path("edit/<str:pk>/", views.EditDeviceView.as_view(), name="edit"), path("edit/<str:pk>/", views.EditDeviceView.as_view(), name="edit"),
path("<str:pk>/", views.DetailsView.as_view(), name="details"), path("<str:pk>/", views.DetailsView.as_view(), name="details"),
path("<str:pk>/user_property/add", views.AddUserPropertyView.as_view(), name="add_user_property"), path("<str:pk>/user_property/add",
path("user_property/<int:pk>/delete", views.DeleteUserPropertyView.as_view(), name="delete_user_property"), views.AddUserPropertyView.as_view(), name="add_user_property"),
path("user_property/<int:pk>/update", views.UpdateUserPropertyView.as_view(), name="update_user_property"), path("<str:device_id>/user_property/<int:pk>/delete",
views.DeleteUserPropertyView.as_view(), name="delete_user_property"),
path("<str:device_id>/user_property/<int:pk>/update",
views.UpdateUserPropertyView.as_view(), name="update_user_property"),
path("<str:pk>/public/", views.PublicDeviceWebView.as_view(), name="device_web"), path("<str:pk>/public/", views.PublicDeviceWebView.as_view(), name="device_web"),
] ]

View file

@ -53,35 +53,6 @@ class NewDeviceView(DashboardView, FormView):
return response return response
# class AddToLotView(DashboardView, FormView):
# template_name = "list_lots.html"
# title = _("Add to lots")
# breadcrumb = "lot / add to lots"
# success_url = reverse_lazy('dashboard:unassigned_devices')
# form_class = LotsForm
# def get_context_data(self, **kwargs):
# context = super().get_context_data(**kwargs)
# lots = Lot.objects.filter(owner=self.request.user)
# lot_tags = LotTag.objects.filter(owner=self.request.user)
# context.update({
# 'lots': lots,
# 'lot_tags':lot_tags,
# })
# return context
# def get_form(self):
# form = super().get_form()
# form.fields["lots"].queryset = Lot.objects.filter(owner=self.request.user)
# return form
# def form_valid(self, form):
# form.devices = self.get_session_devices()
# form.save()
# response = super().form_valid(form)
# return response
class EditDeviceView(DashboardView, UpdateView): class EditDeviceView(DashboardView, UpdateView):
template_name = "new_device.html" template_name = "new_device.html"
title = _("Update Device") title = _("Update Device")
@ -132,15 +103,19 @@ class DetailsView(DashboardView, TemplateView):
state_definitions = StateDefinition.objects.filter( state_definitions = StateDefinition.objects.filter(
institution=self.request.user.institution institution=self.request.user.institution
).order_by('order') ).order_by('order')
device_states = State.objects.filter(snapshot_uuid=uuid).order_by('-date')
device_logs = DeviceLog.objects.filter(
snapshot_uuid=uuid).order_by('-date')
device_notes = Note.objects.filter(snapshot_uuid=uuid).order_by('-date')
context.update({ context.update({
'object': self.object, 'object': self.object,
'snapshot': last_evidence, 'snapshot': last_evidence,
'lot_tags': lot_tags, 'lot_tags': lot_tags,
'dpps': dpps, 'dpps': dpps,
"state_definitions": state_definitions, "state_definitions": state_definitions,
"device_states": State.objects.filter(snapshot_uuid=uuid).order_by('-date'), "device_states": device_states,
"device_logs": DeviceLog.objects.filter(snapshot_uuid=uuid).order_by('-date'), "device_logs": device_logs,
"device_notes": Note.objects.filter(snapshot_uuid=uuid).order_by('-date'), "device_notes": device_notes,
}) })
return context return context
@ -231,7 +206,10 @@ class AddUserPropertyView(DeviceLogMixin, CreateView):
def get_form_kwargs(self): def get_form_kwargs(self):
pk = self.kwargs.get('pk') pk = self.kwargs.get('pk')
institution = self.request.user.institution institution = self.request.user.institution
self.property = get_object_or_404(SystemProperty, owner=institution, value=pk) self.property = SystemProperty.objects.filter(
owner=institution, value=pk).first()
if not self.property:
raise Http404
return super().get_form_kwargs() return super().get_form_kwargs()
@ -244,6 +222,7 @@ class AddUserPropertyView(DeviceLogMixin, CreateView):
context['pk'] = self.kwargs.get('pk') context['pk'] = self.kwargs.get('pk')
return context return context
class UpdateUserPropertyView(DeviceLogMixin, UpdateView): class UpdateUserPropertyView(DeviceLogMixin, UpdateView):
template_name = "new_user_property.html" template_name = "new_user_property.html"
title = _("Update User Property") title = _("Update User Property")
@ -251,21 +230,15 @@ class UpdateUserPropertyView(DeviceLogMixin, UpdateView):
model = UserProperty model = UserProperty
fields = ("key", "value") fields = ("key", "value")
def get_queryset(self): def get_form_kwargs(self):
pk = self.kwargs.get('pk') pk = self.kwargs.get('pk')
institution = self.request.user.institution institution = self.request.user.institution
return UserProperty.objects.filter(pk=pk, owner=institution) self.object = get_object_or_404(UserProperty, owner=institution, pk=pk)
self.old_key = self.object.key
self.old_value = self.object.value
return super().get_form_kwargs()
def form_valid(self, form): def form_valid(self, form):
old_instance = self.get_object()
old_key = old_instance.key
old_value = old_instance.value
form.instance.owner = self.request.user.institution
form.instance.user = self.request.user
form.instance.type = UserProperty.Type.USER
new_key = form.cleaned_data['key'] new_key = form.cleaned_data['key']
new_value = form.cleaned_data['value'] new_value = form.cleaned_data['value']
@ -273,27 +246,25 @@ class UpdateUserPropertyView(DeviceLogMixin, UpdateView):
super().form_valid(form) super().form_valid(form)
messages.success(self.request, _("Property updated successfully.")) messages.success(self.request, _("Property updated successfully."))
log_message = _("<Updated> UserProperty: {}: {} to {}: {}".format( log_message = _("<Updated> UserProperty: {}: {} to {}: {}".format(
old_key, self.old_key,
old_value, self.old_value,
new_key, new_key,
new_value new_value
)) ))
self.log_registry(form.instance.uuid, log_message) self.log_registry(form.instance.uuid, log_message)
# return response # return response
return redirect(self.get_success_url()+"#user_properties") return redirect(self.get_success_url())
except IntegrityError: except IntegrityError:
messages.error(self.request, _("Property is already defined.")) messages.error(self.request, _("Property is already defined."))
return self.form_invalid(form) return self.form_invalid(form)
def form_invalid(self, form): def form_invalid(self, form):
super().form_invalid(form) super().form_invalid(form)
return redirect(self.get_success_url()+"#user_properties") return redirect(self.get_success_url())
def get_success_url(self): def get_success_url(self):
return self.request.META.get( pk = self.kwargs.get('device_id')
'HTTP_REFERER', return reverse_lazy('device:details', args=[pk]) + "#user_properties"
reverse_lazy('device:details', args=[self.object.pk])
)
class DeleteUserPropertyView(DeviceLogMixin, DeleteView): class DeleteUserPropertyView(DeviceLogMixin, DeleteView):
@ -302,9 +273,12 @@ class DeleteUserPropertyView(DeviceLogMixin, DeleteView):
def get_queryset(self): def get_queryset(self):
return UserProperty.objects.filter(owner=self.request.user.institution) return UserProperty.objects.filter(owner=self.request.user.institution)
#using post() method because delete() method from DeleteView has some issues with messages framework #using post() method because delete() method from DeleteView has some issues
# with messages framework
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
self.object = self.get_object() pk = self.kwargs.get('pk')
institution = self.request.user.institution
self.object = get_object_or_404(UserProperty, owner=institution, pk=pk)
self.object.delete() self.object.delete()
msg = _("<Deleted> User Property: {}:{}".format( msg = _("<Deleted> User Property: {}:{}".format(
@ -314,12 +288,8 @@ class DeleteUserPropertyView(DeviceLogMixin, DeleteView):
self.log_registry(self.object.uuid, msg) self.log_registry(self.object.uuid, msg)
messages.info(self.request, _("User property deleted successfully.")) messages.info(self.request, _("User property deleted successfully."))
return self.handle_success()
def handle_success(self):
return redirect(self.get_success_url()) return redirect(self.get_success_url())
def get_success_url(self): def get_success_url(self):
pk = self.object.pk pk = self.kwargs.get('device_id')
url = reverse_lazy('device:details', args=[pk]) return reverse_lazy('device:details', args=[pk]) + "#user_properties"
return self.request.META.get('HTTP_REFERER', url) + "#user_properties"

View file

@ -0,0 +1,20 @@
# Generated by Django 5.0.6 on 2025-01-31 10:33
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('lot', '0005_alter_lotproperty_type'),
('user', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddConstraint(
model_name='lotproperty',
constraint=models.UniqueConstraint(fields=('key', 'lot'), name='property_unique_type_key_lot'),
),
]

View file

@ -53,3 +53,9 @@ class LotProperty (Property):
USER = 1, "User" USER = 1, "User"
type = models.SmallIntegerField(choices=Type.choices, default=Type.USER) type = models.SmallIntegerField(choices=Type.choices, default=Type.USER)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["key", "lot"], name="property_unique_type_key_lot")
]

View file

@ -36,7 +36,7 @@
{% endfor %} {% endfor %}
</div> </div>
<div class="container"> <div class="container">
<a class="btn btn-grey" href="{% url 'dashboard:unassigned_devices' %}">{% translate "Cancel" %}</a> <a class="btn btn-grey" href="{% url 'lot:properties' lot_id %}">{% translate "Cancel" %}</a>
<input class="btn btn-green-admin" type="submit" name="submit" value="{% translate 'Save' %}" /> <input class="btn btn-green-admin" type="submit" name="submit" value="{% translate 'Save' %}" />
</div> </div>

View file

@ -10,8 +10,8 @@
<div class="row"> <div class="row">
<div class="tab-pane fade show active" id="details"> <div class="tab-pane fade show active" id="details">
<div class="btn-group dropdown ml-1 mt-1" uib-dropdown=""> <div class="d-flex justify-content-end mt-1 mb-3">
<a href="{% url 'lot:add_property' lot.pk %}" class="btn btn-primary"> <a href="{% url 'lot:add_property' lot.pk %}" class="btn btn-green-admin d-flex align-items-center">
<i class="bi bi-plus"></i> <i class="bi bi-plus"></i>
Add new lot Property Add new lot Property
@ -20,34 +20,35 @@
</div> </div>
<h5 class="card-title mt-2">Properties</h5> <h5 class="card-title mt-2">Properties</h5>
<table class="table table-striped"> <table class="table table-hover table-bordered table-responsive align-middle">
<thead> <thead class="table-light">
<tr> <tr>
<th scope="col">Key</th> <th scope="col">{% trans 'Key' %}</th>
<th scope="col">Value</th> <th scope="col">{% trans 'Value' %}</th>
<th scope="col" data-type="date" data-format="YYYY-MM-DD hh:mm">Created on</th> <th scope="col" data-type="date" class="text-end" data-format="YYYY-MM-DD HH:mm">{% trans 'Created on' %}</th>
<th></th> <th scope="col" width="5%" class="text-end"></th>
<th></th> </tr>
</tr>
</thead> </thead>
<tbody> <tbody>
{% for a in properties %} {% for a in properties %}
<tr> <tr>
<td>{{ a.key }}</td> <td>{{ a.key }}</td>
<td>{{ a.value }}</td> <td>{{ a.value }}</td>
<td>{{ a.created }}</td> <td class="text-end">{{ a.created }}</td>
<td class="text-center"> <td>
<a href="#" class="text-info" data-bs-toggle="modal" data-bs-target="#editPropertyModal{{ a.id }}"> <div class="btn-group ">
<i class="bi bi-pencil"></i> <button type="button" class="btn btn-sm btn-outline-info d-flex align-items-center" data-bs-toggle="modal" data-bs-target="#editPropertyModal{{ a.id }}">
</a> <i class="bi bi-pencil me-1"></i>
</td> {% trans 'Edit' %}
<td class="text-center"> </button>
<a href="#" class="text-danger" data-bs-toggle="modal" data-bs-target="#deletePropertyModal{{ a.id }}"> <button type="button" class="btn btn-sm btn-outline-danger d-flex align-items-center" data-bs-toggle="modal" data-bs-target="#deletePropertyModal{{ a.id }}">
<i class="bi bi-trash"></i> <i class="bi bi-trash me-1"></i>
</a> {% trans 'Delete' %}
</td> </button>
</div>
</td>
</tr> </tr>
<div class="modal fade" id="editPropertyModal{{ a.id }}" tabindex="-1" aria-labelledby="editPropertyModalLabel{{ a.id }}" aria-hidden="true"> <div class="modal fade" id="editPropertyModal{{ a.id }}" tabindex="-1" aria-labelledby="editPropertyModalLabel{{ a.id }}" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
@ -75,7 +76,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="modal fade" id="deletePropertyModal{{ a.id }}" tabindex="-1" aria-labelledby="deletePropertyModalLabel{{ a.id }}" aria-hidden="true"> <div class="modal fade" id="deletePropertyModal{{ a.id }}" tabindex="-1" aria-labelledby="deletePropertyModalLabel{{ a.id }}" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
@ -97,7 +98,7 @@
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>

View file

@ -1,3 +1,4 @@
from django.db import IntegrityError
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.shortcuts import get_object_or_404, redirect, Http404 from django.shortcuts import get_object_or_404, redirect, Http404
from django.contrib import messages from django.contrib import messages
@ -98,7 +99,8 @@ class AddToLotView(DashboardView, FormView):
def get_form(self): def get_form(self):
form = super().get_form() form = super().get_form()
form.fields["lots"].queryset = Lot.objects.filter(owner=self.request.user.institution) form.fields["lots"].queryset = Lot.objects.filter(
owner=self.request.user.institution)
return form return form
def form_valid(self, form): def form_valid(self, form):
@ -132,7 +134,9 @@ class LotsTagsView(DashboardView, TemplateView):
self.title += " {}".format(tag.name) self.title += " {}".format(tag.name)
self.breadcrumb += " {}".format(tag.name) self.breadcrumb += " {}".format(tag.name)
show_closed = self.request.GET.get('show_closed', 'false') == 'true' show_closed = self.request.GET.get('show_closed', 'false') == 'true'
lots = Lot.objects.filter(owner=self.request.user.institution).filter(type=tag, closed=show_closed) lots = Lot.objects.filter(owner=self.request.user.institution).filter(
type=tag, closed=show_closed
)
context.update({ context.update({
'lots': lots, 'lots': lots,
'title': self.title, 'title': self.title,
@ -178,8 +182,13 @@ class AddLotPropertyView(DashboardView, CreateView):
form.instance.user = self.request.user form.instance.user = self.request.user
form.instance.lot = self.lot form.instance.lot = self.lot
form.instance.type = LotProperty.Type.USER form.instance.type = LotProperty.Type.USER
response = super().form_valid(form) try:
return response response = super().form_valid(form)
messages.success(self.request, _("Property successfully added."))
return response
except IntegrityError:
messages.error(self.request, _("Property is already defined."))
return self.form_invalid(form)
def get_form_kwargs(self): def get_form_kwargs(self):
pk = self.kwargs.get('pk') pk = self.kwargs.get('pk')
@ -188,6 +197,11 @@ class AddLotPropertyView(DashboardView, CreateView):
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
return kwargs return kwargs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['lot_id'] = self.lot.id
return context
class UpdateLotPropertyView(DashboardView, UpdateView): class UpdateLotPropertyView(DashboardView, UpdateView):
template_name = "properties.html" template_name = "properties.html"
@ -198,31 +212,33 @@ class UpdateLotPropertyView(DashboardView, UpdateView):
def get_form_kwargs(self): def get_form_kwargs(self):
pk = self.kwargs.get('pk') pk = self.kwargs.get('pk')
lot_property = get_object_or_404(LotProperty, pk=pk, owner=self.request.user.institution) lot_property = get_object_or_404(
LotProperty,
pk=pk,
owner=self.request.user.institution
)
if not lot_property: if not lot_property:
raise Http404 raise Http404
lot_pk = lot_property.lot.pk
self.success_url = reverse_lazy('lot:properties', args=[lot_pk])
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
kwargs['instance'] = lot_property kwargs['instance'] = lot_property
return kwargs return kwargs
def form_valid(self, form): def form_valid(self, form):
old_key= self.object.key try:
old_value = self.object.value response = super().form_valid(form)
new_key = form.cleaned_data['key'] messages.success(self.request, _("Property updated successfully."))
new_value = form.cleaned_data['value'] return response
except IntegrityError:
messages.error(self.request, _("Property is already defined."))
return self.form_invalid(form)
form.instance.owner = self.request.user.institution def form_invalid(self, form):
form.instance.user = self.request.user super().form_invalid(form)
form.instance.type = LotProperty.Type.USER return redirect(self.get_success_url())
response = super().form_valid(form)
messages.success(self.request, _("Lot property updated successfully."))
return response
def get_success_url(self):
return self.request.META.get('HTTP_REFERER', reverse_lazy('device:details', args=[self.object.pk]))
class DeleteLotPropertyView(DashboardView, DeleteView): class DeleteLotPropertyView(DashboardView, DeleteView):
@ -230,18 +246,15 @@ class DeleteLotPropertyView(DashboardView, DeleteView):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
self.pk = kwargs['pk'] self.pk = kwargs['pk']
referer = request.META.get('HTTP_REFERER')
if not referer:
raise Http404("No referer header found")
self.object = get_object_or_404( self.object = get_object_or_404(
self.model, self.model,
pk=self.pk, pk=self.pk,
owner=self.request.user.institution owner=self.request.user.institution
) )
old_value = self.object.key lot_pk = self.object.lot.pk
self.object.delete() self.object.delete()
messages.success(self.request, _("Lot property deleted successfully.")) messages.success(self.request, _("Lot property deleted successfully."))
self.success_url = reverse_lazy('lot:properties', args=[lot_pk])
# Redirect back to the original URL # Redirect back to the original URL
return redirect(referer) return redirect(self.success_url)