diff --git a/gulashromstore/settings.py b/gulashromstore/settings.py index fa96210..c0220f0 100644 --- a/gulashromstore/settings.py +++ b/gulashromstore/settings.py @@ -123,5 +123,11 @@ USE_TZ = True STATIC_URL = '/static/' +MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') + + AUTH_USER_MODEL = 'users.User' + +SLOT_COUNT = 7 diff --git a/gulashromstore/urls.py b/gulashromstore/urls.py index c7c74f5..ebb033c 100644 --- a/gulashromstore/urls.py +++ b/gulashromstore/urls.py @@ -1,21 +1,12 @@ -"""gulashromstore URL Configuration - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/1.10/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.conf.urls import url, include - 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) -""" -from django.conf.urls import url +from django.conf.urls import url, include +from django.conf.urls.static import static from django.contrib import admin +from gulashromstore.settings import MEDIA_URL, MEDIA_ROOT + urlpatterns = [ + url(r'^roms/', include('roms.urls')), url(r'^admin/', admin.site.urls), ] + +urlpatterns += static(MEDIA_URL, document_root=MEDIA_ROOT) diff --git a/roms/admin.py b/roms/admin.py index 87f5db9..1f49dde 100644 --- a/roms/admin.py +++ b/roms/admin.py @@ -4,15 +4,46 @@ from taggit_helpers.admin import TaggitListFilter, TaggitTabularInline from roms.models import Rom, RomFile +from gulashromstore.settings import SLOT_COUNT + class RomFileInline(admin.TabularInline): model = RomFile + max_num = SLOT_COUNT + min_num = SLOT_COUNT class RomAdmin(admin.ModelAdmin): + list_display = ('name', 'approved', 'tag_list') list_filter = [TaggitListFilter] + actions = ['mark_approved', 'mark_disapproved'] + + fieldsets = ((None, {'fields' : ('name', 'description', 'cover', 'approved')}),) inlines = [ RomFileInline, TaggitTabularInline ] + + def tag_list(self, obj): + return u", ".join(obj.tag_list()) + + def mark_approved(self, request, queryset): + rows_updated = queryset.update(approved=True) + if rows_updated == 1: + message_bit = "One rom was" + else: + message_bit = "%d roms were" % rows_updated + self.message_user(request, "%s successfully marked as approved." % message_bit) + mark_approved.short_description = "Mark selected roms as approved" + + def mark_disapproved(self, request, queryset): + rows_updated = queryset.update(approved=False) + if rows_updated == 1: + message_bit = "One rom was" + else: + message_bit = "%d roms were" % rows_updated + self.message_user(request, "%s successfully marked as disapproved." % message_bit) + mark_disapproved.short_description = "Mark selected roms as disapproved" + + admin.site.register(Rom, RomAdmin) diff --git a/roms/migrations/0001_initial.py b/roms/migrations/0001_initial.py index 8e00971..ac1e225 100644 --- a/roms/migrations/0001_initial.py +++ b/roms/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.10.5 on 2017-02-01 20:33 +# Generated by Django 1.10.5 on 2017-03-18 17:30 from __future__ import unicode_literals from django.db import migrations, models @@ -23,6 +23,7 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=128, verbose_name='name')), ('description', models.TextField(verbose_name='description')), ('cover', models.ImageField(upload_to='', verbose_name='cover image')), + ('approved', models.BooleanField(verbose_name='approved')), ('tags', taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags')), ], ), @@ -30,9 +31,13 @@ class Migration(migrations.Migration): name='RomFile', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('slot', models.IntegerField(verbose_name='slot numer')), + ('slot', models.IntegerField(choices=[(1, 'Slot 1'), (2, 'Slot 2'), (3, 'Slot 3'), (4, 'Slot 4'), (5, 'Slot 5'), (6, 'Slot 6')], verbose_name='slot')), ('binary', models.FileField(upload_to='', verbose_name='binary')), ('rom', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='roms.Rom', verbose_name='rom')), ], ), + migrations.AlterUniqueTogether( + name='romfile', + unique_together=set([('rom', 'slot')]), + ), ] diff --git a/roms/models.py b/roms/models.py index a0974bc..ce0c1c1 100644 --- a/roms/models.py +++ b/roms/models.py @@ -1,19 +1,50 @@ +import os +import uuid + from django.db import models +from django.core.exceptions import ValidationError from taggit.managers import TaggableManager +from gulashromstore.settings import SLOT_COUNT + +def upload_cover_to(instance, filename): + _, ext = os.path.splitext(filename) + return "covers/%s.%s" % (uuid.uuid4(), ext) + +def upload_binary_to(instance, filename): + return "roms/%s.bin" % uuid.uuid4() + + class Rom(models.Model): name = models.CharField("name", max_length = 128) description = models.TextField("description") - cover = models.ImageField("cover image") + cover = models.ImageField("cover image", upload_to=upload_cover_to) + approved = models.BooleanField("approved") tags = TaggableManager() + def tag_list(self): + return [t.name for t in self.tags.all()] + + def to_json(self): + json = { + 'id' : self.pk, + 'name' : self.name, + 'description' : self.description, + 'tags' : self.tag_list(), + 'roms' : {romfile.slot : romfile.binary.url for romfile in self.romfile_set.all()} + } + + return json + + + class RomFile(models.Model): - SLOT_CHOICES = [(i, "Slot %d" % i) for i in range(1,7)] + SLOT_CHOICES = [(i, "Slot %d" % i) for i in range(1, SLOT_COUNT+1)] rom = models.ForeignKey(Rom, verbose_name = "rom") slot = models.IntegerField("slot", choices=SLOT_CHOICES) - binary = models.FileField("binary") + binary = models.FileField("binary", upload_to=upload_binary_to) class Meta: unique_together = ('rom', 'slot') diff --git a/roms/urls.py b/roms/urls.py new file mode 100644 index 0000000..b5e63f7 --- /dev/null +++ b/roms/urls.py @@ -0,0 +1,8 @@ +from django.conf.urls import include, url + +from roms.views import RomListJson, RomDetailViewJson + +urlpatterns = [ + url(r'json/$', RomListJson.as_view()), + url(r'json/(?P[0-9]+)/$', RomDetailViewJson.as_view()) +] diff --git a/roms/views.py b/roms/views.py index 91ea44a..6403e5a 100644 --- a/roms/views.py +++ b/roms/views.py @@ -1,3 +1,29 @@ -from django.shortcuts import render +from django.views.generic.list import ListView +from django.views.generic.detail import DetailView +from django.http import JsonResponse -# Create your views here. +from roms.models import Rom + + +class RomListJson(ListView): + def get_queryset(self): + return Rom.objects.all().filter(approved = True) + + def render_to_response(self, context, **response_kwargs): + queryset = self.get_queryset() + + json = {} + for rom in queryset: + json[rom.id] = rom.name + + return JsonResponse(json, **response_kwargs, safe=False) + + + +class RomDetailViewJson(DetailView): + model = Rom + pk_url_kwarg = 'id' + + def render_to_response(self, context, **response_kwargs): + rom = self.get_object() + return JsonResponse(rom.to_json(), **response_kwargs, safe=False)