From 66e012f9947c34bc296642ad53f66899196720af Mon Sep 17 00:00:00 2001 From: Oly Date: Thu, 27 Apr 2017 14:02:33 +0100 Subject: [PATCH] switched to mapping model, lookup in the api does not yet work --- mhackspace/rfid/admin.py | 25 ++++++++++- .../migrations/0003_auto_20170427_0743.py | 29 +++++++++++++ mhackspace/rfid/models.py | 41 ++++++++++--------- mhackspace/rfid/serializers.py | 7 ++-- mhackspace/rfid/tests/tests.py | 4 +- mhackspace/rfid/views.py | 16 ++++---- 6 files changed, 89 insertions(+), 33 deletions(-) create mode 100644 mhackspace/rfid/migrations/0003_auto_20170427_0743.py diff --git a/mhackspace/rfid/admin.py b/mhackspace/rfid/admin.py index c793c98..bd6db72 100644 --- a/mhackspace/rfid/admin.py +++ b/mhackspace/rfid/admin.py @@ -1,14 +1,35 @@ # -*- coding: utf-8 -*- from django.contrib import admin from django.contrib.admin import ModelAdmin +from django.forms.models import ModelChoiceField -from mhackspace.rfid.models import Device, Rfid +from mhackspace.rfid.models import Device, Rfid, DeviceAuth @admin.register(Device) class DeviceAdmin(ModelAdmin): list_display = ('name', 'identifier') + @admin.register(Rfid) class RfidAdmin(ModelAdmin): - list_display = ('code',) + list_display = ('code', 'description') + + +# Probably need to look at this again +@admin.register(DeviceAuth) +class DeviceAuthAdmin(ModelAdmin): + list_display = ('rfid', 'device') + + class CustomModelChoiceField(ModelChoiceField): + def label_from_instance(self, obj): + return obj.description + ' - ' + str(obj.user) + + def formfield_for_foreignkey(self, db_field, request, **kwargs): + if db_field.name == "rfid": + return self.CustomModelChoiceField( + Rfid.objects.all(), + initial=request.user) + + return super(DeviceAuthAdmin, self).formfield_for_foreignkey( + db_field, request, **kwargs) diff --git a/mhackspace/rfid/migrations/0003_auto_20170427_0743.py b/mhackspace/rfid/migrations/0003_auto_20170427_0743.py new file mode 100644 index 0000000..510a7f8 --- /dev/null +++ b/mhackspace/rfid/migrations/0003_auto_20170427_0743.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2017-04-27 07:43 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('rfid', '0002_auto_20170420_0730'), + ] + + operations = [ + migrations.CreateModel( + name='DeviceAuth', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rfid.Device')), + ('rfid', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rfid.Rfid')), + ], + ), + migrations.AddField( + model_name='device', + name='members', + field=models.ManyToManyField(through='rfid.DeviceAuth', to='rfid.Rfid'), + ), + ] diff --git a/mhackspace/rfid/models.py b/mhackspace/rfid/models.py index 3b727ed..fdb7435 100644 --- a/mhackspace/rfid/models.py +++ b/mhackspace/rfid/models.py @@ -13,25 +13,23 @@ from django.utils.translation import ugettext_lazy as _ # users rfid card to user mapping, user can have more than one card class Rfid(models.Model): + code = models.PositiveIntegerField() + description = models.CharField(_('Short rfid description'), blank=True, max_length=255) user = models.ForeignKey( settings.AUTH_USER_MODEL, null=True, blank=True, # related_name='rfid_user' ) - code = models.PositiveIntegerField() - description = models.CharField(_('Short rfid description'), blank=True, max_length=255) def __str__(self): return self.description + def name(self): + return self.user.name + # description of a device like door, print, laser cutter class Device(models.Model): - user = models.ForeignKey( - settings.AUTH_USER_MODEL, - null=True, blank=True, - # related_name='rfid_user' - ) # user = models.ManyToMany(settings.AUTH_USER_MODEL) identifier = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) @@ -39,22 +37,25 @@ class Device(models.Model): description = models.CharField(_('Short description of what the device does'), blank=True, max_length=255) added_date = models.DateTimeField(default=timezone.now, editable=False) + members = models.ManyToManyField(Rfid, through='DeviceAuth') + + user = models.ForeignKey( + settings.AUTH_USER_MODEL, + null=True, blank=True, + # related_name='rfid_user' + ) + def __str__(self): return self.name +# http://stackoverflow.com/questions/4443190/djangos-manytomany-relationship-with-additional-fields # many to many, lookup user from rfid model then get there user_id and the device to check if auth allowed -# class DeviceAuth(models.Model): -# user = models.ForeignKey( -# settings.AUTH_USER_MODEL, -# null=True, blank=True, -# default=None, -# related_name='user_auth' -# ) +class DeviceAuth(models.Model): + rfid = models.ForeignKey( + Rfid, + ) -# device = models.ForeignKey( -# Device, -# null=True, blank=True, -# default=None, -# related_name='device' -# ) + device = models.ForeignKey( + Device, + ) diff --git a/mhackspace/rfid/serializers.py b/mhackspace/rfid/serializers.py index 20efdcb..f93fad3 100644 --- a/mhackspace/rfid/serializers.py +++ b/mhackspace/rfid/serializers.py @@ -1,6 +1,6 @@ from rest_framework import serializers -from mhackspace.rfid.models import Device +from mhackspace.rfid.models import Device, DeviceAuth class Task(object): @@ -8,10 +8,11 @@ class Task(object): for field in ('id', 'name', 'owner', 'status'): setattr(self, field, kwargs.get(field, None)) + class DeviceSerializer(serializers.ModelSerializer): class Meta: - model = Device - fields = ('name', ) + model = DeviceAuth + fields = ('__all__') class AuthSerializer(serializers.Serializer): diff --git a/mhackspace/rfid/tests/tests.py b/mhackspace/rfid/tests/tests.py index 418e702..f8bab6b 100644 --- a/mhackspace/rfid/tests/tests.py +++ b/mhackspace/rfid/tests/tests.py @@ -7,7 +7,7 @@ from test_plus.test import TestCase from rest_framework.test import APIRequestFactory from rest_framework.test import RequestsClient -from mhackspace.rfid.models import Device, Rfid +from mhackspace.rfid.models import Device, Rfid, DeviceAuth from mhackspace.users.models import User @@ -32,6 +32,8 @@ class ApiTests(TestCase): self.device.save() self.rfid = Rfid(code='1', user=self.user) self.rfid.save() + self.auth = DeviceAuth(rfid=self.rfid, device=self.device) + self.save() def testAuth(self): factory = APIRequestFactory() diff --git a/mhackspace/rfid/views.py b/mhackspace/rfid/views.py index 4752720..21103ed 100644 --- a/mhackspace/rfid/views.py +++ b/mhackspace/rfid/views.py @@ -2,9 +2,9 @@ import logging from rest_framework.response import Response from rest_framework import viewsets from rest_framework import status -from mhackspace.rfid.models import Device, Rfid +from mhackspace.rfid.models import Device, Rfid, DeviceAuth from mhackspace.rfid.serializers import DeviceSerializer, AuthSerializer -from django.core.exceptions import ObjectDoesNotExist +from django.core.exceptions import ObjectDoesNotExist, ValidationError logger = logging.getLogger(__name__) @@ -20,18 +20,20 @@ class AuthUserWithDeviceViewSet(viewsets.ViewSet): serializer_class = AuthSerializer def list(self, request): - serializer = AuthSerializer( - instance={'name': '1', 'rfid': '1', 'device': '1'}) + serializer = DeviceSerializer( + DeviceAuth.objects.all(), many=True) return Response(serializer.data) def post(self, request, format=None): try: rfid = Rfid.objects.get(code=request.data.get('rfid')) - device = Device.objects.get(user=rfid.user, identifier=request.data.get('device')) + device = Device.objects.get(identifier=request.data.get('device')) + deviceAuth = DeviceAuth.objects.get(device=device.identifier, rfid=rfid.id) except ObjectDoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) - except: - logger.exception("An error occurred") + except ValidationError: + # except: + # logger.exception("An error occurred") return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR) serializer = AuthSerializer( instance={'name': device.name, 'rfid': rfid.code, 'device': device.identifier})