diff --git a/api_v2/admin.py b/api_v2/admin.py index 0fbbaddd..bb7a3c0a 100644 --- a/api_v2/admin.py +++ b/api_v2/admin.py @@ -1,13 +1,6 @@ from django.contrib import admin -from api_v2.models import Weapon -from api_v2.models import Armor -from api_v2.models import Item, ItemSet - -from api_v2.models import Document -from api_v2.models import License -from api_v2.models import Publisher -from api_v2.models import Ruleset +from api_v2.models import * # Register your models here. @@ -17,7 +10,7 @@ class FromDocumentModelAdmin(admin.ModelAdmin): class ItemModelAdmin(admin.ModelAdmin): - list_display = ['key','category','name'] + list_display = ['key', 'category', 'name'] admin.site.register(Weapon, admin_class=FromDocumentModelAdmin) admin.site.register(Armor, admin_class=FromDocumentModelAdmin) @@ -25,6 +18,10 @@ class ItemModelAdmin(admin.ModelAdmin): admin.site.register(Item, admin_class=ItemModelAdmin) admin.site.register(ItemSet, admin_class=FromDocumentModelAdmin) +admin.site.register(Race, admin_class=FromDocumentModelAdmin) +admin.site.register(Trait) +admin.site.register(Feat, admin_class=FromDocumentModelAdmin) + admin.site.register(Document) admin.site.register(License) admin.site.register(Publisher) diff --git a/api_v2/migrations/0002_feat.py b/api_v2/migrations/0002_feat.py new file mode 100644 index 00000000..efb19ce4 --- /dev/null +++ b/api_v2/migrations/0002_feat.py @@ -0,0 +1,27 @@ +# Generated by Django 3.2.20 on 2023-08-13 01:53 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('api_v2', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Feat', + fields=[ + ('name', models.CharField(help_text='Name of the item.', max_length=100)), + ('desc', models.TextField(help_text='Description of the game content item. Markdown.')), + ('prerequisite_desc', models.CharField(help_text='Prerequisite for the game content item.', max_length=100)), + ('key', models.CharField(help_text='Unique key for the Item.', max_length=100, primary_key=True, serialize=False)), + ('document', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api_v2.document')), + ], + options={ + 'verbose_name_plural': 'feats', + }, + ), + ] diff --git a/api_v2/migrations/0003_race_trait.py b/api_v2/migrations/0003_race_trait.py new file mode 100644 index 00000000..2c5e1aa6 --- /dev/null +++ b/api_v2/migrations/0003_race_trait.py @@ -0,0 +1,39 @@ +# Generated by Django 3.2.20 on 2023-08-13 02:16 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('api_v2', '0002_feat'), + ] + + operations = [ + migrations.CreateModel( + name='Race', + fields=[ + ('name', models.CharField(help_text='Name of the item.', max_length=100)), + ('desc', models.TextField(help_text='Description of the game content item. Markdown.')), + ('key', models.CharField(help_text='Unique key for the Item.', max_length=100, primary_key=True, serialize=False)), + ('document', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api_v2.document')), + ('subrace_of', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='api_v2.race')), + ], + options={ + 'verbose_name_plural': 'races', + }, + ), + migrations.CreateModel( + name='Trait', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(help_text='Name of the item.', max_length=100)), + ('desc', models.TextField(help_text='Description of the game content item. Markdown.')), + ('race', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api_v2.race')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/api_v2/models/__init__.py b/api_v2/models/__init__.py index ce45e4c3..ed49dcac 100644 --- a/api_v2/models/__init__.py +++ b/api_v2/models/__init__.py @@ -2,9 +2,10 @@ The initialization for models for open5e's api v2. """ -from .abstracts import HasName -from .abstracts import HasDescription -from .abstracts import Object +#from .abstracts import HasName +#from .abstracts import HasDescription +#from .abstracts import Object + from .item import Item from .item import ItemSet @@ -13,6 +14,11 @@ from .weapon import Weapon +from .race import Trait +from .race import Race + +from .feat import Feat + from .document import Document from .document import License from .document import Publisher diff --git a/api_v2/models/race.py b/api_v2/models/race.py index 7fe81b77..7fd5221e 100644 --- a/api_v2/models/race.py +++ b/api_v2/models/race.py @@ -12,7 +12,7 @@ class Trait(HasName, HasDescription): Each trait ties to an individual race or subrace. """ - race = models.ForeignKey('Race') + race = models.ForeignKey('Race', on_delete=models.CASCADE) class Race(HasName, HasDescription, FromDocument): @@ -22,12 +22,12 @@ class Race(HasName, HasDescription, FromDocument): This model can be used to represent races based on parent=null. """ - subrace_of = models.ForeignKey('self', null=True) + subrace_of = models.ForeignKey('self', null=True, on_delete=models.CASCADE) @property def is_subrace(self): """Returns whether the object is a subrace.""" - return self.parent == null + return self.subrace_of != null class Meta: """To assist with the UI layer.""" diff --git a/api_v2/serializers.py b/api_v2/serializers.py index 78bfb786..61c04f6c 100644 --- a/api_v2/serializers.py +++ b/api_v2/serializers.py @@ -118,3 +118,11 @@ class ItemSetSerializer(GameContentSerializer): class Meta: model = models.ItemSet fields = '__all__' + + +class FeatSerializer(GameContentSerializer): + key = serializers.ReadOnlyField() + + class Meta: + model = models.feat + fields = '__all__' diff --git a/api_v2/views.py b/api_v2/views.py index f4ce840b..2b092d44 100644 --- a/api_v2/views.py +++ b/api_v2/views.py @@ -163,3 +163,23 @@ class ArmorViewSet(viewsets.ReadOnlyModelViewSet): queryset = models.Armor.objects.all().order_by('pk') serializer_class = serializers.ArmorSerializer filterset_class = ArmorFilterSet + + +class FeatFilterSet(FilterSet): + class Meta: + model = models.Feat + fields = { + 'key': ['in', 'iexact', 'exact' ], + 'name': ['iexact', 'exact'], + 'document__key': ['in','iexact','exact'], + } + + +class FeatViewSet(viewsets.ReadOnlyModelViewSet): + """ + list: API endpoint for returning a list of feats. + retrieve: API endpoint for returning a particular feat. + """ + queryset = models.Feat.objects.all().order_by('pk') + serializer_class = serializers.FeatSerializer + filterset_class = FeatFilterSet diff --git a/server/urls.py b/server/urls.py index 4bb6eea2..b8b960f8 100644 --- a/server/urls.py +++ b/server/urls.py @@ -60,6 +60,7 @@ router_v2.register(r'weapons',views_v2.WeaponViewSet) router_v2.register(r'armor',views_v2.ArmorViewSet) router_v2.register(r'rulesets',views_v2.RulesetViewSet) + router_v2.register(r'feats',views_v2.FeatViewSet) # Wire up our API using automatic URL routing. # Additionally, we include login URLs for the browsable API.