diff --git a/server/server/models.py b/server/server/models.py index 6b5899c..871a29e 100644 --- a/server/server/models.py +++ b/server/server/models.py @@ -2,6 +2,9 @@ from django.db import models class Guild(models.Model): + """ + This model is used to store the guild data. + """ id = models.AutoField(primary_key=True) name = models.CharField(max_length=200) tag = models.CharField(max_length=10) @@ -16,6 +19,9 @@ class Guild(models.Model): class Player(models.Model): + """ + This model is used to store the player data. + """ id = models.AutoField(primary_key=True) name = models.CharField(max_length=200) creation_date = models.DateTimeField("date created", auto_now_add=True) @@ -29,9 +35,13 @@ class Player(models.Model): class PlayerGuild(models.Model): + """ + This model is used to store the player's guild data. + """ id = models.AutoField(primary_key=True) player = models.ForeignKey(Player, on_delete=models.CASCADE, related_name="guilds") guild = models.ForeignKey(Guild, on_delete=models.CASCADE, related_name="players") + role = models.CharField(max_length=200) # admin, officer, member, etc. eventually tie to permissions and account stuff creation_date = models.DateTimeField("date created", auto_now_add=True) def __str__(self): @@ -43,6 +53,9 @@ class PlayerGuild(models.Model): class Game(models.Model): + """ + This model is used to store the game data. + """ id = models.AutoField(primary_key=True) name = models.CharField(max_length=200) creation_date = models.DateTimeField("date created", auto_now_add=True) @@ -55,7 +68,12 @@ class Game(models.Model): verbose_name_plural = "Games" -class PlayerGameProfile(models.Model): +class PlayerGameData(models.Model): + """ + This model is used to store the game data for a player. + Anything can be stored in the data field, but it will + be validated against the schema before being stored. + """ id = models.AutoField(primary_key=True) player = models.ForeignKey( Player, on_delete=models.CASCADE, related_name="game_profiles" @@ -64,43 +82,53 @@ class PlayerGameProfile(models.Model): Game, on_delete=models.CASCADE, related_name="player_profiles" ) creation_date = models.DateTimeField("date created", auto_now_add=True) + data = models.JSONField() def __str__(self): return f"{self.player} - {self.game}" class Meta: - verbose_name = "Player Game Profile" - verbose_name_plural = "Player Game Profiles" + verbose_name = "Player Game Data" + verbose_name_plural = "Player Game Data" -class WowProfile(models.Model): +class GuildGameDataSchema(models.Model): + """ + This model is used to store the schema for the game data. + Right now it is associated with guild until we determine + which entity should own the schema. + + Player Game Data will be validated against this schema. + """ id = models.AutoField(primary_key=True) - player_game_profile = models.OneToOneField( - PlayerGameProfile, on_delete=models.CASCADE, related_name="wow_profile" + guild = models.ForeignKey( + Guild, on_delete=models.CASCADE, related_name="schemas" ) - level = models.IntegerField() - class_name = models.CharField(max_length=200) + game = models.ForeignKey( + Game, on_delete=models.CASCADE, related_name="schemas" + ) + schema = models.JSONField() + + def __str__(self): + return f"{self.guild} - {self.game}" + + class Meta: + verbose_name = "Guild Game Data Schema" + verbose_name_plural = "Guild Game Data Schemas" + + +class WowClasses(models.Model): + """ + Example of a model that could be used to pre-populate + dropdowns in the UI. + """ + id = models.AutoField(primary_key=True) + name = models.CharField(max_length=200) creation_date = models.DateTimeField("date created", auto_now_add=True) def __str__(self): - return f"{self.player_game_profile.player} - {self.player_game_profile.game}" + return self.name class Meta: - verbose_name = "WoW Profile" - verbose_name_plural = "WoW Profiles" - - -class ValorantProfile(models.Model): - id = models.AutoField(primary_key=True) - player_game_profile = models.OneToOneField( - PlayerGameProfile, on_delete=models.CASCADE, related_name="valorant_profile" - ) - rank = models.CharField(max_length=200) - creation_date = models.DateTimeField("date created", auto_now_add=True) - - def __str__(self): - return f"{self.player_game_profile.player} - {self.player_game_profile.game}" - - class Meta: - verbose_name = "Valorant Profile" - verbose_name_plural = "Valorant Profiles" + verbose_name = "WoW Class" + verbose_name_plural = "WoW Classes" \ No newline at end of file diff --git a/server/server/serializers.py b/server/server/serializers.py index 979160e..9ae8b77 100644 --- a/server/server/serializers.py +++ b/server/server/serializers.py @@ -3,10 +3,10 @@ from .models import ( Guild, Player, Game, - PlayerGameProfile, - WowProfile, - ValorantProfile, PlayerGuild, + PlayerGameData, + GuildGameDataSchema, + WowClasses, ) @@ -20,7 +20,7 @@ class GuildSerializer(serializers.ModelSerializer): class PlayerSerializer(serializers.ModelSerializer): class Meta: model = Player - fields = ["id", "name", "guild", "creation_date"] + fields = ["id", "name", "creation_date"] read_only_fields = ["id", "creation_date"] @@ -31,25 +31,27 @@ class GameSerializer(serializers.ModelSerializer): read_only_fields = ["id", "creation_date"] -class PlayerGameProfileSerializer(serializers.ModelSerializer): +class PlayerGameDataSerializer(serializers.ModelSerializer): class Meta: - model = PlayerGameProfile - fields = ["id", "player", "game", "creation_date"] + model = PlayerGameData + fields = ["id", "player", "game", "creation_date", "data"] read_only_fields = ["id", "creation_date"] + def validate_data(self, value): + game_id = self.initial_data["game"] + # pull schema from guildgameschema + schema = GuildGameDataSchema.objects.get(game=game_id) + # validate data against schema + # if valid, return value + # if not valid, raise serializers.ValidationError("Invalid data") + return value -class WowProfileSerializer(serializers.ModelSerializer): + +class GuildGameDataSchemaSerializer(serializers.ModelSerializer): class Meta: - model = WowProfile - fields = ["id", "player_game_profile", "level", "class_name", "creation_date"] - read_only_fields = ["id", "creation_date"] - - -class ValorantProfileSerializer(serializers.ModelSerializer): - class Meta: - model = ValorantProfile - fields = ["id", "player_game_profile", "rank", "creation_date"] - read_only_fields = ["id", "creation_date"] + model = GuildGameDataSchema + fields = ["id", "guild", "game", "schema"] + read_only_fields = ["id"] class PlayerGuildSerializer(serializers.ModelSerializer): @@ -57,3 +59,10 @@ class PlayerGuildSerializer(serializers.ModelSerializer): model = PlayerGuild fields = ["id", "player", "guild", "creation_date"] read_only_fields = ["id", "creation_date"] + + +class WowClassesSerializer(serializers.ModelSerializer): + class Meta: + model = WowClasses + fields = ["id", "name", "creation_date"] + read_only_fields = ["id", "creation_date"] \ No newline at end of file