Initial rfid models, to think about any thoughts ?
remove mapping model on base on @scollins suggestion Updated models, enabled it in the admin backup to get an idea of the structure. will need to rebuild, updating restframework current state of experiment into rfid api Change docs url started looking into web tokens Refactor models More experimenting Custom view now works, needs tiding up and data to test
This commit is contained in:
parent
28e0cd8f94
commit
69af967ae6
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
Repository for the maidstone hackspace website, feel free to fork this site for your own Hackspace.
|
Repository for the maidstone hackspace website, feel free to fork this site for your own Hackspace.
|
||||||
|
|
||||||
|
|
||||||
** Requirements
|
** Requirements
|
||||||
Before getting started make sure you have git, docker and docker-compose installed on your machine.
|
Before getting started make sure you have git, docker and docker-compose installed on your machine.
|
||||||
The simplest way to setup this site is to use docker-compose so please install that from this site
|
The simplest way to setup this site is to use docker-compose so please install that from this site
|
||||||
|
@ -47,7 +46,7 @@ docker-compose -f dev.yml run --rm django python manage.py makemigrations
|
||||||
docker-compose -f dev.yml run --rm django python manage.py migrate
|
docker-compose -f dev.yml run --rm django python manage.py migrate
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
*** Create the admin user.
|
*** Create the admin user.
|
||||||
Once created you can login at http://127.0.0.1:8180/admin
|
Once created you can login at http://127.0.0.1:8180/trustee
|
||||||
#+BEGIN_SRC sh
|
#+BEGIN_SRC sh
|
||||||
docker-compose -f dev.yml run --rm django python manage.py createsuperuser
|
docker-compose -f dev.yml run --rm django python manage.py createsuperuser
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
|
@ -80,6 +80,7 @@ THIRD_PARTY_APPS = (
|
||||||
'whitenoise.runserver_nostatic',
|
'whitenoise.runserver_nostatic',
|
||||||
'stdimage',
|
'stdimage',
|
||||||
'rest_framework',
|
'rest_framework',
|
||||||
|
'django_filters',
|
||||||
'draceditor',
|
'draceditor',
|
||||||
'haystack',
|
'haystack',
|
||||||
'djconfig',
|
'djconfig',
|
||||||
|
@ -138,6 +139,7 @@ LOCAL_APPS = (
|
||||||
'mhackspace.blog',
|
'mhackspace.blog',
|
||||||
'mhackspace.core',
|
'mhackspace.core',
|
||||||
'mhackspace.requests',
|
'mhackspace.requests',
|
||||||
|
'mhackspace.rfid',
|
||||||
)
|
)
|
||||||
|
|
||||||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
|
||||||
|
@ -446,10 +448,12 @@ REST_FRAMEWORK = {
|
||||||
'rest_framework.filters.OrderingFilter'
|
'rest_framework.filters.OrderingFilter'
|
||||||
),
|
),
|
||||||
'DEFAULT_PERMISSION_CLASSES': (
|
'DEFAULT_PERMISSION_CLASSES': (
|
||||||
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',
|
# 'rest_framework.permissions.IsAuthenticated',
|
||||||
|
# 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',
|
||||||
),
|
),
|
||||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||||
'rest_framework.authentication.BasicAuthentication',
|
# 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
|
||||||
|
# 'rest_framework.authentication.BasicAuthentication',
|
||||||
'rest_framework.authentication.SessionAuthentication',
|
'rest_framework.authentication.SessionAuthentication',
|
||||||
'rest_framework.authentication.TokenAuthentication',
|
'rest_framework.authentication.TokenAuthentication',
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.conf.urls import include, url
|
from django.conf.urls import include, url
|
||||||
from django.conf.urls.static import static
|
from django.conf.urls.static import static
|
||||||
|
@ -9,6 +10,7 @@ from django.views import defaults as default_views
|
||||||
from django.contrib.auth import views as auth_views
|
from django.contrib.auth import views as auth_views
|
||||||
from django.contrib.sitemaps.views import sitemap
|
from django.contrib.sitemaps.views import sitemap
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
|
from rest_framework.documentation import include_docs_urls
|
||||||
|
|
||||||
from mhackspace.contact.views import contact
|
from mhackspace.contact.views import contact
|
||||||
from mhackspace.members.views import MemberListView
|
from mhackspace.members.views import MemberListView
|
||||||
|
@ -20,21 +22,28 @@ from mhackspace.blog.views import PostViewSet, CategoryViewSet, BlogPost, PostLi
|
||||||
from mhackspace.blog.sitemaps import PostSitemap, CategorySitemap
|
from mhackspace.blog.sitemaps import PostSitemap, CategorySitemap
|
||||||
from mhackspace.feeds.views import FeedViewSet, ArticleViewSet
|
from mhackspace.feeds.views import FeedViewSet, ArticleViewSet
|
||||||
from mhackspace.requests.views import RequestsForm, RequestsList
|
from mhackspace.requests.views import RequestsForm, RequestsList
|
||||||
|
from mhackspace.rfid.views import DeviceViewSet, AuthUserWithDeviceViewSet
|
||||||
|
|
||||||
|
|
||||||
from wiki.urls import get_pattern as get_wiki_pattern
|
from wiki.urls import get_pattern as get_wiki_pattern
|
||||||
from django_nyt.urls import get_pattern as get_nyt_pattern
|
from django_nyt.urls import get_pattern as get_nyt_pattern
|
||||||
|
from rest_framework_jwt.views import obtain_jwt_token
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
router.register(r'posts', PostViewSet)
|
router.register(r'posts', PostViewSet)
|
||||||
router.register(r'categories', CategoryViewSet)
|
router.register(r'categories', CategoryViewSet)
|
||||||
router.register(r'feeds', FeedViewSet)
|
router.register(r'feeds', FeedViewSet)
|
||||||
router.register(r'articles', ArticleViewSet)
|
router.register(r'articles', ArticleViewSet)
|
||||||
|
router.register(r'rfid', DeviceViewSet)
|
||||||
|
router.register(r'rfidAuth', AuthUserWithDeviceViewSet, base_name='device')
|
||||||
|
|
||||||
|
|
||||||
sitemaps = {
|
sitemaps = {
|
||||||
'posts': PostSitemap,
|
'posts': PostSitemap,
|
||||||
'category': CategorySitemap,
|
'category': CategorySitemap,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', TemplateView.as_view(template_name='pages/home.html'), name='home'),
|
url(r'^$', TemplateView.as_view(template_name='pages/home.html'), name='home'),
|
||||||
url(r'^about/$', TemplateView.as_view(template_name='pages/about.html'), name='about'),
|
url(r'^about/$', TemplateView.as_view(template_name='pages/about.html'), name='about'),
|
||||||
|
@ -68,6 +77,9 @@ urlpatterns = [
|
||||||
# Django Admin, use {% url 'admin:index' %}
|
# Django Admin, use {% url 'admin:index' %}
|
||||||
url(r'{}'.format(settings.ADMIN_URL), admin.site.urls),
|
url(r'{}'.format(settings.ADMIN_URL), admin.site.urls),
|
||||||
|
|
||||||
|
url(r'^api-token-auth/', obtain_jwt_token),
|
||||||
|
url(r'^api/docs/', include_docs_urls(title='Hackspace API')),
|
||||||
|
|
||||||
# User management
|
# User management
|
||||||
url(r'^users/', include('mhackspace.users.urls', namespace='users')),
|
url(r'^users/', include('mhackspace.users.urls', namespace='users')),
|
||||||
url(r'^accounts/', include('allauth.urls')),
|
url(r'^accounts/', include('allauth.urls')),
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.contrib.admin import ModelAdmin
|
||||||
|
|
||||||
|
from mhackspace.rfid.models import Device, Rfid
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Device)
|
||||||
|
class DeviceAdmin(ModelAdmin):
|
||||||
|
list_display = ('name',)
|
||||||
|
|
||||||
|
@admin.register(Rfid)
|
||||||
|
class RfidAdmin(ModelAdmin):
|
||||||
|
list_display = ('code',)
|
|
@ -0,0 +1,47 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2017-04-14 21:15
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Device',
|
||||||
|
fields=[
|
||||||
|
('identifier', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||||
|
('name', models.CharField(max_length=255, verbose_name='Device name')),
|
||||||
|
('description', models.CharField(blank=True, max_length=255, verbose_name='Short description of what the device does')),
|
||||||
|
('added_date', models.DateTimeField(default=django.utils.timezone.now, editable=False)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='DeviceAuth',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('device', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='device', to='rfid.Device')),
|
||||||
|
('user', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='user_auth', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Rfid',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('code', models.PositiveIntegerField()),
|
||||||
|
('description', models.CharField(blank=True, max_length=255, verbose_name='Short rfid description')),
|
||||||
|
('user', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='rfid_user', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,39 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.11 on 2017-04-20 07:30
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('rfid', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='deviceauth',
|
||||||
|
name='device',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='deviceauth',
|
||||||
|
name='user',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='device',
|
||||||
|
name='user',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='rfid',
|
||||||
|
name='user',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='DeviceAuth',
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,60 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals, absolute_import
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from django.utils import timezone
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
# just brainstorming so we can start playing with this,
|
||||||
|
# be nice to make this a 3rd party django installable app ?
|
||||||
|
|
||||||
|
|
||||||
|
# users rfid card to user mapping, user can have more than one card
|
||||||
|
class Rfid(models.Model):
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
name = models.CharField(_('Device name'), max_length=255)
|
||||||
|
description = models.CharField(_('Short description of what the device does'), blank=True, max_length=255)
|
||||||
|
added_date = models.DateTimeField(default=timezone.now, editable=False)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
# 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'
|
||||||
|
# )
|
||||||
|
|
||||||
|
# device = models.ForeignKey(
|
||||||
|
# Device,
|
||||||
|
# null=True, blank=True,
|
||||||
|
# default=None,
|
||||||
|
# related_name='device'
|
||||||
|
# )
|
|
@ -0,0 +1,32 @@
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from mhackspace.rfid.models import Device
|
||||||
|
|
||||||
|
|
||||||
|
class Task(object):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
for field in ('id', 'name', 'owner', 'status'):
|
||||||
|
setattr(self, field, kwargs.get(field, None))
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Device
|
||||||
|
fields = ('name', )
|
||||||
|
|
||||||
|
|
||||||
|
class AuthSerializer(serializers.Serializer):
|
||||||
|
name = serializers.CharField(max_length=255)
|
||||||
|
rfid = serializers.CharField(max_length=255)
|
||||||
|
device_id = serializers.CharField(max_length=255)
|
||||||
|
|
||||||
|
# def create(self, validated_data):
|
||||||
|
# return Task(id=None, **validated_data)
|
||||||
|
|
||||||
|
# def update(self, instance, validated_data):
|
||||||
|
# for field, value in validated_data.items():
|
||||||
|
# setattr(instance, field, value)
|
||||||
|
# return instance
|
||||||
|
|
||||||
|
# class Meta:
|
||||||
|
# fields = ('name', )
|
|
@ -0,0 +1,58 @@
|
||||||
|
import sys
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from io import StringIO
|
||||||
|
from django.core.management import call_command
|
||||||
|
from test_plus.test import TestCase
|
||||||
|
from rest_framework.test import APIRequestFactory
|
||||||
|
from rest_framework.test import RequestsClient
|
||||||
|
|
||||||
|
from mhackspace.rfid.models import Device
|
||||||
|
from mhackspace.user.models import User
|
||||||
|
|
||||||
|
|
||||||
|
# http://www.django-rest-framework.org/api-guide/testing/
|
||||||
|
|
||||||
|
class MigrationTestCase(TestCase):
|
||||||
|
|
||||||
|
def testRollback(self):
|
||||||
|
out = StringIO()
|
||||||
|
sys.stout = out
|
||||||
|
call_command('migrate', 'rfid', 'zero', stdout=out)
|
||||||
|
call_command('migrate', 'rfid', stdout=out)
|
||||||
|
self.assertIn("... OK\n", out.getvalue())
|
||||||
|
|
||||||
|
class ApiTests(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
Device(name='device01').save()
|
||||||
|
User(name='User01').save()
|
||||||
|
Rfid(code=1, user=1).save()
|
||||||
|
|
||||||
|
def testAuth(self):
|
||||||
|
factory = APIRequestFactory()
|
||||||
|
request = factory.get('/rfid/')
|
||||||
|
|
||||||
|
def testSamsMadness(self):
|
||||||
|
client = RequestsClient()
|
||||||
|
response = client.post(
|
||||||
|
'http://127.0.0.1:8180/api/v1/rfidAuth/?format=json',
|
||||||
|
data={'rfid':'1', 'device': '1'})
|
||||||
|
print(response)
|
||||||
|
assert response.status_code == 200
|
||||||
|
self.assertEquals(response.json().get('results'), [{'name': 'device01'}])
|
||||||
|
|
||||||
|
|
||||||
|
def testAuthUserWithDevice(self):
|
||||||
|
client = RequestsClient()
|
||||||
|
response = client.get('http://127.0.0.1:8180/api/v1/rfid/?format=json')
|
||||||
|
assert response.status_code == 200
|
||||||
|
self.assertEquals(response.json().get('results'), [{'name': 'device01'}])
|
||||||
|
|
||||||
|
|
||||||
|
def testFetchDeviceList(self):
|
||||||
|
client = RequestsClient()
|
||||||
|
response = client.get('http://127.0.0.1:8180/api/v1/rfid/?format=json')
|
||||||
|
assert response.status_code == 200
|
||||||
|
self.assertEquals(response.json().get('results'), [{'name': 'device01'}])
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
from rest_framework import viewsets
|
||||||
|
from mhackspace.rfid.models import Device, Rfid
|
||||||
|
from mhackspace.rfid.serializers import DeviceSerializer, AuthSerializer
|
||||||
|
from django.shortcuts import get_list_or_404, get_object_or_404
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceViewSet(viewsets.ModelViewSet):
|
||||||
|
queryset = Device.objects.all()
|
||||||
|
serializer_class = DeviceSerializer
|
||||||
|
|
||||||
|
|
||||||
|
#https://medium.com/django-rest-framework/django-rest-framework-viewset-when-you-don-t-have-a-model-335a0490ba6f
|
||||||
|
class AuthUserWithDeviceViewSet(viewsets.ViewSet):
|
||||||
|
# http_method_names = ['get', 'post', 'head']
|
||||||
|
serializer_class = AuthSerializer
|
||||||
|
|
||||||
|
def list(self, request):
|
||||||
|
serializer = AuthSerializer(instance={'name': '1','rfid': '1', 'device_id': '1'})
|
||||||
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
def post(self, request, format=None):
|
||||||
|
rfid = Rfid.objects.get(code=request.GET.get('rfid_id'))
|
||||||
|
|
||||||
|
print(rfid.user.device__set(device=request.GET.get('rfid_id')))
|
||||||
|
# = get_object_or_404(Disease, pk=disease_id)
|
||||||
|
|
||||||
|
|
||||||
|
# Device(rfid, device)
|
||||||
|
serializer = AuthSerializer(instance={'name': '1', 'rfid': '1', 'device_id': '1'})
|
||||||
|
return Response(serializer.data)
|
|
@ -21,3 +21,9 @@
|
||||||
[hidden][style="display: block;"] {
|
[hidden][style="display: block;"] {
|
||||||
display: block !important;
|
display: block !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.imgfit {
|
||||||
|
width:100%;
|
||||||
|
height: auto;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
|
@ -61,7 +61,10 @@ git+https://github.com/olymk2/scaffold.git
|
||||||
git+git://github.com/django-wiki/django-wiki.git
|
git+git://github.com/django-wiki/django-wiki.git
|
||||||
|
|
||||||
djangorestframework==3.6.3
|
djangorestframework==3.6.3
|
||||||
|
djangorestframework-jwt
|
||||||
django-filter==1.0.2
|
django-filter==1.0.2
|
||||||
|
coreapi
|
||||||
|
# api libraries end
|
||||||
|
|
||||||
draceditor==1.1.8
|
draceditor==1.1.8
|
||||||
# django-spirit
|
# django-spirit
|
||||||
|
|
Loading…
Reference in New Issue