xapian #1

Merged
cayop merged 26 commits from xapian into master 2024-09-17 10:11:28 +00:00
19 changed files with 262 additions and 115 deletions
Showing only changes of commit e2f9855954 - Show all commits

View File

@ -5,6 +5,7 @@ from django.core.exceptions import PermissionDenied
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from device.models import Device from device.models import Device
from snapshot.models import Annotation
from lot.models import LotTag from lot.models import LotTag
@ -45,7 +46,10 @@ class DashboardView(LoginRequiredMixin):
def get_session_devices(self): def get_session_devices(self):
# import pdb; pdb.set_trace() # import pdb; pdb.set_trace()
dev_ids = self.request.session.pop("devices", []) dev_ids = self.request.session.pop("devices", [])
self._devices = Device.objects.filter(id__in=dev_ids).filter(owner=self.request.user)
self._devices = []
for x in Annotation.objects.filter(value__in=dev_ids).filter(owner=self.request.user).distinct():
self._devices.append(Device(id=x.value))
return self._devices return self._devices
@ -53,7 +57,7 @@ class DetailsMixin(DashboardView, TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.pk = kwargs['pk'] self.pk = kwargs['pk']
self.object = get_object_or_404(self.model, pk=self.pk) self.object = get_object_or_404(self.model, pk=self.pk, owner=self.request.user)
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):

View File

@ -90,11 +90,6 @@
{% trans 'Unassigned devices' %} {% trans 'Unassigned devices' %}
</a> </a>
</li> </li>
<li class="nav-item">
<a class="nav-link{% if path == 'admin_people_new' %} active2{% endif %}" href="{% url 'dashboard:all_devices' %}">
{% trans 'All devices' %}
</a>
</li>
</ul> </ul>
</li> </li>
<li class="nav-item"> <li class="nav-item">

View File

@ -5,6 +5,5 @@ app_name = 'dashboard'
urlpatterns = [ urlpatterns = [
path("", views.UnassignedDevicesView.as_view(), name="unassigned_devices"), path("", views.UnassignedDevicesView.as_view(), name="unassigned_devices"),
path("all/", views.AllDevicesView.as_view(), name="all_devices"),
path("<int:pk>/", views.LotDashboardView.as_view(), name="lot"), path("<int:pk>/", views.LotDashboardView.as_view(), name="lot"),
] ]

View File

@ -17,9 +17,7 @@ class UnassignedDevicesView(InventaryMixin):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
devices = Device.objects.filter( devices = Device.get_unassigned(self.request.user)
owner=self.request.user
).annotate(num_lots=Count('lot')).filter(num_lots=0)
context.update({ context.update({
'devices': devices, 'devices': devices,
@ -28,32 +26,21 @@ class UnassignedDevicesView(InventaryMixin):
return context return context
class AllDevicesView(InventaryMixin):
template_name = "unassigned_devices.html"
section = "All"
title = _("All Devices")
breadcrumb = "Devices / All Devices"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
devices = Device.objects.filter(owner=self.request.user)
context.update({
'devices': devices,
})
return context
class LotDashboardView(InventaryMixin, DetailsMixin): class LotDashboardView(InventaryMixin, DetailsMixin):
template_name = "unassigned_devices.html" template_name = "unassigned_devices.html"
section = "Unassigned" section = "dashboard_lot"
title = _("Lot Devices") title = _("Lot Devices")
breadcrumb = "Devices / Lot Devices" breadcrumb = "Lot / Devices"
model = Lot model = Lot
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
devices = self.object.devices.filter(owner=self.request.user) devices = self.get_devices()
context.update({ context.update({
'devices': devices, 'devices': devices,
}) })
return context return context
def get_devices(self):
chids = self.object.devicelot_set.all().values_list("device_id", flat=True).distinct()
return [Device(id=x) for x in chids]

View File

@ -1,3 +1,17 @@
from django import forms from django import forms
from snapshot.models import Annotation
class DeviceForm2(forms.ModelForm):
class Meta:
model = Annotation
fields = ['key', 'value']
class DeviceForm(forms.Form):
name = forms.CharField()
value = forms.CharField()
DeviceFormSet = forms.formset_factory(form=DeviceForm, extra=1)

View File

@ -0,0 +1,18 @@
# Generated by Django 5.0.6 on 2024-07-18 17:30
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("device", "0003_device_manufacturer"),
("lot", "0002_remove_lot_devices_devicelot"),
("snapshot", "0002_remove_annotation_device"),
]
operations = [
migrations.DeleteModel(
name="Device",
),
]

View File

@ -3,9 +3,10 @@ from django.db import models
from utils.constants import STR_SM_SIZE, STR_SIZE, STR_EXTEND_SIZE, ALGOS from utils.constants import STR_SM_SIZE, STR_SIZE, STR_EXTEND_SIZE, ALGOS
from snapshot.models import Annotation, Snapshot from snapshot.models import Annotation, Snapshot
from user.models import User from user.models import User
from lot.models import DeviceLot
class Device(models.Model): class Device:
class Types(models.TextChoices): class Types(models.TextChoices):
DESKTOP = "Desktop" DESKTOP = "Desktop"
LAPTOP = "Laptop" LAPTOP = "Laptop"
@ -22,17 +23,18 @@ class Device(models.Model):
BATTERY = "Battery" BATTERY = "Battery"
CAMERA = "Camera" CAMERA = "Camera"
owner = models.ForeignKey(User, on_delete=models.CASCADE)
type = models.CharField(max_length=STR_SIZE, blank=True, null=True)
manufacturer = models.CharField(max_length=STR_EXTEND_SIZE, blank=True, null=True)
model = models.CharField(max_length=STR_EXTEND_SIZE, blank=True, null=True)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
# the id is the chid of the device
self.id = kwargs["id"]
self.pk = self.id
self.algorithm = None
self.owner = None
self.annotations = [] self.annotations = []
self.hids = [] self.hids = []
self.uuids = [] self.uuids = []
self.snapshots = [] self.snapshots = []
super().__init__(*args, **kwargs) self.last_snapshot = None
self.get_last_snapshot()
def initial(self): def initial(self):
self.get_annotations() self.get_annotations()
@ -41,21 +43,29 @@ class Device(models.Model):
self.get_snapshots() self.get_snapshots()
def get_annotations(self): def get_annotations(self):
if self.annotations:
return self.annotations
self.annotations = Annotation.objects.filter( self.annotations = Annotation.objects.filter(
device=self, type=Annotation.Type.SYSTEM,
owner=self.owner value=self.id
).order_by("-created") ).order_by("-created")
if self.annotations.count():
self.algorithm = self.annotations[0].key
self.owner = self.annotations[0].owner
return self.annotations
def get_uuids(self): def get_uuids(self):
for a in self.annotations: for a in self.get_annotations():
if not a.uuid in self.uuids: if not a.uuid in self.uuids:
self.uuids.append(a.uuid) self.uuids.append(a.uuid)
def get_hids(self): def get_hids(self):
if not self.annotations: annotations = self.get_annotations()
self.get_annotations()
self.hids = self.annotations.filter( self.hids = annotations.filter(
type=Annotation.Type.SYSTEM, type=Annotation.Type.SYSTEM,
key__in=ALGOS.keys(), key__in=ALGOS.keys(),
).values_list("value", flat=True) ).values_list("value", flat=True)
@ -67,14 +77,47 @@ class Device(models.Model):
self.snapshots = [Snapshot(u) for u in self.uuids] self.snapshots = [Snapshot(u) for u in self.uuids]
def get_last_snapshot(self): def get_last_snapshot(self):
if not self.snapshots: annotations = self.get_annotations()
self.get_snapshots() if annotations:
annotation = annotations.first()
self.last_snapshot = Snapshot(annotation.uuid)
if self.snapshots: def last_uuid(self):
return self.snapshots[0] return self.uuids[0]
@classmethod @classmethod
def get_unassigned(cls, user): def get_unassigned(cls, user):
return cls.objects.filter( chids = DeviceLot.objects.filter(lot__owner=user).values_list("device_id", flat=True).distinct()
owner=user annotations = Annotation.objects.filter(
).annotate(num_lots=models.Count('lot')).filter(num_lots=0) owner=user,
type=Annotation.Type.SYSTEM,
).exclude(value__in=chids).values_list("value", flat=True).distinct()
return [cls(id=x) for x in annotations]
# return cls.objects.filter(
# owner=user
# ).annotate(num_lots=models.Count('lot')).filter(num_lots=0)
@property
def manufacturer(self):
if not self.last_snapshot:
self.get_last_snapshot()
return self.last_snapshot.doc['device']['manufacturer']
@property
def type(self):
if not self.last_snapshot:
self.get_last_snapshot()
return self.last_snapshot.doc['device']['type']
@property
def model(self):
if not self.last_snapshot:
self.get_last_snapshot()
return self.last_snapshot.doc['device']['model']
@property
def type(self):
if not self.last_snapshot:
self.get_last_snapshot()
return self.last_snapshot.doc['device']['type']

View File

@ -26,9 +26,6 @@
<li class="nav-items"> <li class="nav-items">
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#components">Components</button> <button class="nav-link" data-bs-toggle="tab" data-bs-target="#components">Components</button>
</li> </li>
<li class="nav-items">
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#traceabiliy">Traceability log</button>
</li>
<li class="nav-items"> <li class="nav-items">
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#snapshots">Snapshots</button> <button class="nav-link" data-bs-toggle="tab" data-bs-target="#snapshots">Snapshots</button>
</li> </li>
@ -47,7 +44,6 @@
(<a href="{% url 'device:edit' object.id %}">Edit Device</a>) (<a href="{% url 'device:edit' object.id %}">Edit Device</a>)
</div> </div>
<div class="col-lg-9 col-md-8"> <div class="col-lg-9 col-md-8">
{% if object.hid %}Snapshot{% else %}Placeholder{% endif %}
</div> </div>
</div> </div>
@ -56,29 +52,24 @@
<div class="col-lg-9 col-md-8">{{ object.id }}</div> <div class="col-lg-9 col-md-8">{{ object.id }}</div>
</div> </div>
<div class="row">
<div class="col-lg-3 col-md-4 label ">Id device internal</div>
<div class="col-lg-9 col-md-8"></div>
</div>
<div class="row"> <div class="row">
<div class="col-lg-3 col-md-4 label ">Type</div> <div class="col-lg-3 col-md-4 label ">Type</div>
<div class="col-lg-9 col-md-8">{{ snapshot.doc.device.type }}</div> <div class="col-lg-9 col-md-8">{{ object.type }}</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-lg-3 col-md-4 label">Manufacturer</div> <div class="col-lg-3 col-md-4 label">Manufacturer</div>
<div class="col-lg-9 col-md-8">{{ snapshot.doc.device.manufacturer|default:"" }}</div> <div class="col-lg-9 col-md-8">{{ object.manufacturer|default:"" }}</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-lg-3 col-md-4 label">Model</div> <div class="col-lg-3 col-md-4 label">Model</div>
<div class="col-lg-9 col-md-8">{{ snapshot.doc.device.model|default:"" }}</div> <div class="col-lg-9 col-md-8">{{ object.model|default:"" }}</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-lg-3 col-md-4 label">Serial Number</div> <div class="col-lg-3 col-md-4 label">Serial Number</div>
<div class="col-lg-9 col-md-8">{{ snapshot.doc.device.serialNumber|default:"" }}</div> <div class="col-lg-9 col-md-8">{{ object.last_snapshot.doc.device.serialNumber|default:"" }}</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-lg-3 col-md-4 label">Identifiers</div> <div class="col-lg-3 col-md-4 label">Identifiers</div>
@ -132,7 +123,7 @@
{% for tag in lot_tags %} {% for tag in lot_tags %}
<h5 class="card-title">{{ tag }}</h5> <h5 class="card-title">{{ tag }}</h5>
{% for lot in object.lot_set.filter %} {% for lot in tag.lot_set.filter %}
{% if lot.type == tag %} {% if lot.type == tag %}
<div class="row"> <div class="row">
<div class="col"> <div class="col">
@ -171,32 +162,10 @@
</table> </table>
</div> </div>
<div class="tab-pane fade profile-overview" id="traceability">
<h5 class="card-title">Traceability log Details</h5>
<div class="list-group col-6">
<div class="list-group-item d-flex justify-content-between align-items-center">
Snapshot ✓
<small class="text-muted">14:07 23-06-2024</small>
</div>
<div class="list-group-item d-flex justify-content-between align-items-center">
EraseCrypto ✓
<small class="text-muted">14:07 23-06-2024</small>
</div>
<div class="list-group-item d-flex justify-content-between align-items-center">
EraseCrypto ✓
<small class="text-muted">14:07 23-06-2024</small>
</div>
</div>
</div>
<div class="tab-pane fade profile-overview" id="components"> <div class="tab-pane fade profile-overview" id="components">
<h5 class="card-title">Components last snapshot</h5> <h5 class="card-title">Components last snapshot</h5>
<div class="list-group col-6"> <div class="list-group col-6">
{% for c in snapshot.components %} {% for c in object.last_snapshot.doc.components %}
<div class="list-group-item"> <div class="list-group-item">
<div class="d-flex w-100 justify-content-between"> <div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">{{ c.type }}</h5> <h5 class="mb-1">{{ c.type }}</h5>

View File

@ -22,11 +22,34 @@
</div> </div>
</div> </div>
{% endif %} {% endif %}
{% bootstrap_form form %} {# bootstrap_form form #}
<div class="form-actions-no-box"> <div class="form-actions-no-box">
<a class="btn btn-grey" href="{% url 'dashboard:unassigned_devices' %}">{% translate "Cancel" %}</a> <a class="btn btn-grey" href="{% url 'dashboard:unassigned_devices' %}">{% 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>
</form>
<script>
function addForm(button) {
var formCount = parseInt(document.getElementById('id_form-TOTAL_FORMS').value);
var formCopy = document.querySelector('.dynamic-form').cloneNode(true);
formCopy.style.display = 'block';
formCopy.innerHTML = formCopy.innerHTML.replace(/__prefix__/g, formCount);
document.getElementById('formset-container').appendChild(formCopy);
document.getElementById('id_form-TOTAL_FORMS').value = formCount + 1;
}
</script>
<form method="post">
{% csrf_token %}
<div id="formset-container">
{% for f in form %}
<div class="dynamic-form" style="display: {% if forloop.first %}block{% else %}none{% endif %};">
{{ f.as_p }}
</div>
{% endfor %}
</div>
<button type="button" onclick="addForm(this);">Add</button>
<button type="submit">Submit</button>
</form> </form>
{% endblock %} {% endblock %}

View File

@ -5,7 +5,7 @@ app_name = 'device'
urlpatterns = [ urlpatterns = [
path("add/", views.NewDeviceView.as_view(), name="add"), path("add/", views.NewDeviceView.as_view(), name="add"),
path("edit/<int:pk>/", views.EditDeviceView.as_view(), name="edit"), path("edit/<str:pk>/", views.EditDeviceView.as_view(), name="edit"),
path("<int:pk>/", views.DetailsView.as_view(), name="details"), path("<str:pk>/", views.DetailsView.as_view(), name="details"),
path("<int:pk>/annotation/add", views.AddAnnotationView.as_view(), name="add_annotation"), path("<str:pk>/annotation/add", views.AddAnnotationView.as_view(), name="add_annotation"),
] ]

View File

@ -6,21 +6,23 @@ from django.utils.translation import gettext_lazy as _
from django.views.generic.edit import ( from django.views.generic.edit import (
CreateView, CreateView,
UpdateView, UpdateView,
FormView,
) )
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from dashboard.mixins import DashboardView, DetailsMixin from dashboard.mixins import DashboardView
from snapshot.models import Annotation from snapshot.models import Annotation
from snapshot.xapian import search from snapshot.xapian import search
from lot.models import LotTag from lot.models import LotTag
from device.models import Device from device.models import Device
from device.forms import DeviceFormSet
class NewDeviceView(DashboardView, CreateView): class NewDeviceView(DashboardView, FormView):
template_name = "new_device.html" template_name = "new_device.html"
title = _("New Device") title = _("New Device")
breadcrumb = "Device / New Device" breadcrumb = "Device / New Device"
success_url = reverse_lazy('dashboard:unassigned_devices') success_url = reverse_lazy('dashboard:unassigned_devices')
model = Device form_class = DeviceFormSet
def form_valid(self, form): def form_valid(self, form):
form.instance.owner = self.request.user form.instance.owner = self.request.user
@ -28,12 +30,41 @@ class NewDeviceView(DashboardView, CreateView):
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")
breadcrumb = "Device / Update Device" breadcrumb = "Device / Update Device"
success_url = reverse_lazy('dashboard:unassigned_devices') success_url = reverse_lazy('dashboard:unassigned_devices')
model = Device model = Annotation
def get_form_kwargs(self): def get_form_kwargs(self):
pk = self.kwargs.get('pk') pk = self.kwargs.get('pk')
@ -43,17 +74,23 @@ class EditDeviceView(DashboardView, UpdateView):
return kwargs return kwargs
class DetailsView(DetailsMixin): class DetailsView(DashboardView, TemplateView):
template_name = "details.html" template_name = "details.html"
title = _("Device") title = _("Device")
breadcrumb = "Device / Details" breadcrumb = "Device / Details"
model = Device model = Annotation
def get(self, request, *args, **kwargs):
self.pk = kwargs['pk']
self.object = Device(id=self.pk)
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
self.object.initial() self.object.initial()
lot_tags = LotTag.objects.filter(owner=self.request.user) lot_tags = LotTag.objects.filter(owner=self.request.user)
context.update({ context.update({
'object': self.object,
'snapshot': self.object.get_last_snapshot(), 'snapshot': self.object.get_last_snapshot(),
'lot_tags': lot_tags, 'lot_tags': lot_tags,
}) })

View File

@ -15,13 +15,14 @@ class LotsForm(forms.Form):
def save(self, commit=True): def save(self, commit=True):
if not commit: if not commit:
return return
for dev in self.devices: for dev in self.devices:
for lot in self._lots: for lot in self._lots:
lot.devices.add(dev.id) lot.add(dev.id)
return return
def remove(self): def remove(self):
for dev in self.devices: for dev in self.devices:
for lot in self._lots: for lot in self._lots:
lot.devices.remove(dev.id) lot.remove(dev.id)
return return

View File

@ -0,0 +1,39 @@
# Generated by Django 5.0.6 on 2024-07-18 17:30
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("lot", "0001_initial"),
]
operations = [
migrations.RemoveField(
model_name="lot",
name="devices",
),
migrations.CreateModel(
name="DeviceLot",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("device_id", models.CharField(max_length=256)),
(
"lot",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="lot.lot"
),
),
],
),
]

View File

@ -7,7 +7,7 @@ from utils.constants import (
) )
from user.models import User from user.models import User
from device.models import Device # from device.models import Device
from snapshot.models import Annotation from snapshot.models import Annotation
@ -19,6 +19,11 @@ class LotTag(models.Model):
return self.name return self.name
class DeviceLot(models.Model):
lot = models.ForeignKey("Lot", on_delete=models.CASCADE)
device_id = models.CharField(max_length=STR_EXTEND_SIZE, blank=False, null=False)
class Lot(models.Model): class Lot(models.Model):
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True) updated = models.DateTimeField(auto_now=True)
@ -28,4 +33,13 @@ class Lot(models.Model):
closed = models.BooleanField(default=True) closed = models.BooleanField(default=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE) owner = models.ForeignKey(User, on_delete=models.CASCADE)
type = models.ForeignKey(LotTag, on_delete=models.CASCADE) type = models.ForeignKey(LotTag, on_delete=models.CASCADE)
devices = models.ManyToManyField(Device)
def add(self, v):
if DeviceLot.objects.filter(lot=self, device_id=v).exists():
return
DeviceLot.objects.create(lot=self, device_id=v)
def remove(self, v):
for d in DeviceLot.objects.filter(lot=self, device_id=v):
d.delete()

View File

@ -6,7 +6,7 @@ from django.views.generic.edit import (
CreateView, CreateView,
DeleteView, DeleteView,
UpdateView, UpdateView,
FormView FormView,
) )
from dashboard.mixins import DashboardView from dashboard.mixins import DashboardView
from lot.models import Lot, LotTag from lot.models import Lot, LotTag

View File

@ -0,0 +1,17 @@
# Generated by Django 5.0.6 on 2024-07-18 17:30
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("snapshot", "0001_initial"),
]
operations = [
migrations.RemoveField(
model_name="annotation",
name="device",
),
]

View File

@ -63,7 +63,6 @@ class Annotation(models.Model):
type = models.SmallIntegerField(choices=Type) type = models.SmallIntegerField(choices=Type)
key = models.CharField(max_length=STR_EXTEND_SIZE) key = models.CharField(max_length=STR_EXTEND_SIZE)
value = models.CharField(max_length=STR_EXTEND_SIZE) value = models.CharField(max_length=STR_EXTEND_SIZE)
device = models.ForeignKey('device.Device', on_delete=models.CASCADE)
class Meta: class Meta:
constraints = [ constraints = [

View File

@ -7,7 +7,6 @@ import hashlib
from datetime import datetime from datetime import datetime
from snapshot.xapian import search, index from snapshot.xapian import search, index
from snapshot.models import Snapshot, Annotation from snapshot.models import Snapshot, Annotation
from device.models import Device
from utils.constants import ALGOS from utils.constants import ALGOS
@ -47,21 +46,10 @@ class Build:
value = algorithms['hidalgo1'] value = algorithms['hidalgo1']
).first() ).first()
if annotation:
device = annotation.device
else:
device = Device.objects.create(
type=self.json["device"]["type"],
manufacturer=self.json["device"]["manufacturer"],
model=self.json["device"]["model"],
owner=self.user
)
for k, v in algorithms.items(): for k, v in algorithms.items():
Annotation.objects.create( Annotation.objects.create(
uuid=self.uuid, uuid=self.uuid,
owner=self.user, owner=self.user,
device=device,
type=Annotation.Type.SYSTEM, type=Annotation.Type.SYSTEM,
key=k, key=k,
value=v value=v

View File

@ -1,10 +1,10 @@
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from django.views.generic.edit import FormView
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.views.generic.edit import ( from django.views.generic.edit import (
CreateView, CreateView,
UpdateView, UpdateView,
FormView,
) )
from dashboard.mixins import DashboardView from dashboard.mixins import DashboardView