Skip to content

Commit

Permalink
Close #12: Contents API (#18)
Browse files Browse the repository at this point in the history
* Added for contents: serializers/deserializers for create/update, factories, api rest and tests
* Improved game views and test for added contents to Game
  • Loading branch information
Virako authored Dec 29, 2018
1 parent 7ff2fac commit bdfaff0
Show file tree
Hide file tree
Showing 26 changed files with 648 additions and 185 deletions.
18 changes: 10 additions & 8 deletions character/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,19 @@ def new_position(self):
return GEOSGeometry('POINT({0} {1})'.format(fake.latitude(), fake.longitude()))


class NPCFactory(DjangoModelFactory):
class Meta:
model = NPC

class CharacterFactory(DjangoModelFactory):
user = SubFactory(UserFactory)
#position = LazyAttribute(new_position)

class Meta:
abstract = True


class PlayerFactory(DjangoModelFactory):
class NPCFactory(CharacterFactory):
class Meta:
model = Player
model = NPC

user = SubFactory(UserFactory)
#position = LazyAttribute(new_position)

class PlayerFactory(CharacterFactory):
class Meta:
model = Player
1 change: 0 additions & 1 deletion character/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from django.db import models
from django.contrib.auth.models import User
from django.contrib.gis.db import models


class Character(models.Model):
Expand Down
17 changes: 12 additions & 5 deletions character/serializers.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
from rest_framework import serializers

from .models import Character
from .models import NPC
from .models import Player


class PlayerSerializer(serializers.ModelSerializer):
class CharacterSerializer(serializers.ModelSerializer):

class Meta:
abstract = True


class PlayerSerializer(CharacterSerializer):

class Meta:
model = Player
fields = ('pk', 'user')
fields = '__all__'


class NPCSerializer(CharacterSerializer):

class NPCSerializer(serializers.ModelSerializer):
class Meta:
model = NPC
fields = ('pk', 'user')
fields = '__all__'


def character_serializer(character):
Expand Down
52 changes: 52 additions & 0 deletions contents/factories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from django.contrib.contenttypes.models import ContentType
from factory.django import DjangoModelFactory
from factory import LazyAttribute, SelfAttribute, SubFactory

from .models import Content
from character.factories import NPCFactory, PlayerFactory
from things.factories import ItemFactory, KnowledgeFactory, RolFactory


class ContentFactory(DjangoModelFactory):
content_id = SelfAttribute('content.pk')
content_type = LazyAttribute(
lambda o: ContentType.objects.get_for_model(o.content))

class Meta:
exclude = ['content']
abstract = True


class ContentPlayerFactory(ContentFactory):
content = SubFactory(PlayerFactory)

class Meta:
model = Content


class ContentNPCFactory(ContentFactory):
content = SubFactory(NPCFactory)

class Meta:
model = Content


class ContentItemFactory(ContentFactory):
content = SubFactory(ItemFactory)

class Meta:
model = Content


class ContentKnowledgeFactory(ContentFactory):
content = SubFactory(KnowledgeFactory)

class Meta:
model = Content


class ContentRolFactory(ContentFactory):
content = SubFactory(RolFactory)

class Meta:
model = Content
1 change: 0 additions & 1 deletion contents/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.contrib.gis.db import models
from django.contrib.gis.geos import GEOSGeometry
from django.utils import timezone

from game.models import Game
Expand Down
83 changes: 83 additions & 0 deletions contents/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
from drf_extra_fields.geo_fields import PointField
from rest_framework import serializers

from .models import Content
from character.models import NPC, Player
from character.serializers import NPCSerializer, PlayerSerializer
from things.models import Item, Knowledge, Rol
from things.serializers import ItemSerializer, KnowledgeSerializer, RolSerializer


SERIALIZERS = [NPCSerializer, PlayerSerializer, ItemSerializer,
KnowledgeSerializer, RolSerializer]

def get_serializer(model):
for ser in SERIALIZERS:
if ser.Meta.model == model:
return ser
return None


class ContentRelatedField(serializers.RelatedField):
queryset = Content.objects.all()

def to_representation(self, value):
if isinstance(value, Player):
return PlayerSerializer(value).data
elif isinstance(value, NPC):
return NPCSerializer(value).data
elif isinstance(value, Item):
return ItemSerializer(value).data
elif isinstance(value, Knowledge):
return KnowledgeSerializer(value).data
elif isinstance(value, Rol):
return RolSerializer(value).data
else:
return None

def to_internal_value(self, value):
if isinstance(value, dict):
return value
else:
return None


class ContentSerializer(serializers.ModelSerializer):
content = ContentRelatedField(required=False)
position = PointField(required=False)

def create(self, data, *args, **kwargs):
content_type = data.get('content_type')
model = content_type.model_class()
content = data.get('content')
if content and data.get('content_id') <= 0:
ser = get_serializer(model)(data=content)
ser.is_valid(raise_exception=True)
content_obj = ser.save()
data['content'] = content_obj
data['content_id'] = content_obj.pk
else:
content_id = data.get('content_id')
content_obj = model.objects.get(pk=content_id)
data['content'] = content_obj
return super().create(data, *args, **kwargs)

def update(self, instance, data, *args, **kwargs):
content_type = data.get('content_type')
model = content_type.model_class()
content = data.get('content')
if content and data.get('content_id') <= 0:
ser = get_serializer(model)(instance.content, data=content)
ser.is_valid(raise_exception=True)
content_obj = ser.save()
data['content'] = content_obj
data['content_id'] = content_obj.pk
else:
content_id = data.get('content_id')
content_obj = model.objects.get(pk=content_id)
data['content'] = content_obj
return super().create(data, *args, **kwargs)

class Meta:
model = Content
fields = '__all__'
Loading

0 comments on commit bdfaff0

Please sign in to comment.