Skip to content
Open

Develop #1728

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions db/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Generated by Django 6.0.5 on 2026-05-17 12:47

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing related_name attribute on this ForeignKey field. According to checklist item #3, you should add related_name to ForeignKey fields to allow access to related models on the Many side.


initial = True
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() method which returns None by default for safer access.


Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() method which returns None by default for safer access.

dependencies = [
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() method which returns None by default for safer access.

]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() method which returns None by default for safer access.


operations = [
migrations.CreateModel(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing related_name attribute on this ForeignKey field. According to checklist item #3, you should add related_name to ForeignKey fields to allow access to related models on the Many side.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() method which returns None by default for safer access.

name='Guild',
fields=[
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing related_name attribute on this ForeignKey field. According to checklist item #3, you should add related_name to ForeignKey fields to allow access to related models on the Many side.

('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True)),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() method which returns None by default for safer access.

('description', models.TextField()),
],
),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() method which returns None by default for safer access.

migrations.CreateModel(
name='Race',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True)),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() method which returns None by default for safer access.

('description', models.TextField(blank=True)),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() method which returns None by default for safer access.

],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() method which returns None by default for safer access.

),
migrations.CreateModel(
name='Player',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nickname', models.CharField(max_length=255, unique=True)),
('email', models.EmailField(max_length=255)),
('bio', models.CharField(max_length=255)),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates task requirements. When guild is deleted, player should NOT be deleted. Use on_delete=models.SET_NULL instead of DO_NOTHING. The 0005 migration eventually fixes this, but the intermediate migration state is incorrect.

('guild', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='db.guild')),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing related_name='players' on Player.race ForeignKey. Required for reverse access to related models.

('race', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='db.race')),
],
),
migrations.CreateModel(
name='Skill',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True)),
('bonus', models.CharField(max_length=255)),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing related_name='skills' on Skill.race ForeignKey. Required for reverse access to related models.

('race', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='db.race')),
],
),
]
18 changes: 18 additions & 0 deletions db/migrations/0002_alter_guild_description.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 6.0.5 on 2026-05-17 13:07

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('db', '0001_initial'),
]

operations = [
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing related_name on ForeignKey - this violates checklist item #3. Add related_name='skills' to allow accessing skills from Race objects.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checklist item #5 requires using .get() method for safe dictionary access. Use players_data[player].get("race", {}) instead of direct indexing to avoid KeyError.

migrations.AlterField(
model_name='guild',
name='description',
field=models.TextField(null=True),
),
]
19 changes: 19 additions & 0 deletions db/migrations/0003_alter_player_guild.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 6.0.5 on 2026-05-17 13:13

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('db', '0002_alter_guild_description'),
]

operations = [
migrations.AlterField(
model_name='player',
name='guild',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='db.guild'),
),
]
24 changes: 24 additions & 0 deletions db/migrations/0004_remove_player_guild_player_created_at.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 6.0.5 on 2026-05-17 13:23

import django.utils.timezone
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('db', '0003_alter_player_guild'),
]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #3: ForeignKey fields must have a related_name to access related models on the Many side. Add related_name='skills' to the race ForeignKey in Skill model.

operations = [
migrations.RemoveField(
model_name='player',
name='guild',
),
Comment on lines +13 to +17
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Migration 0004 removes the guild field from Player but doesn't re-add it. This leaves the Player model incomplete. According to requirements, guild should exist with on_delete=models.SET_NULL and null=True.

migrations.AddField(
model_name='player',
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guild.description is TextField() without null=True, but the requirement states it 'can be null'. This is addressed in migration 0002, but the schema design is incorrect.

name='created_at',
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #3: ForeignKey fields must have a related_name to access related models on the Many side. Add related_name='players' to the race ForeignKey in Player model.

field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #3: ForeignKey fields must have a related_name to access related models on the Many side. Add related_name='players' to the guild ForeignKey in Player model.

preserve_default=False,
),
]
19 changes: 19 additions & 0 deletions db/migrations/0005_player_guild.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 6.0.5 on 2026-05-17 13:29

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('db', '0004_remove_player_guild_player_created_at'),
]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #3: Missing related_name on ForeignKey field. Add related_name='skills' to allow accessing skills from Race objects via race.skills.

operations = [
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #5: Use .get() method instead of direct dictionary access. Use players_data[player].get('race', {}) to safely access nested data.

migrations.AddField(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #5: Use .get() method instead of direct dictionary access.

model_name='player',
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #5: Use .get() method instead of direct dictionary access.

name='guild',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='db.guild'),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #5: Use .get() method instead of direct dictionary access.

),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #5: Use .get() method instead of direct dictionary access.

]
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 6.0.5 on 2026-05-17 13:48

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('db', '0005_player_guild'),
]

operations = [
migrations.AlterField(
model_name='player',
name='guild',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='players', to='db.guild'),
),
migrations.AlterField(
model_name='player',
name='race',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='players', to='db.race'),
),
migrations.AlterField(
model_name='skill',
name='race',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='skills', to='db.race'),
),
]
38 changes: 38 additions & 0 deletions db/models.py
Original file line number Diff line number Diff line change
@@ -1 +1,39 @@
from django.db import models


class Race(models.Model):
name = models.CharField(max_length=255, unique=True)
description = models.TextField(blank=True)


class Skill(models.Model):
name = models.CharField(max_length=255, unique=True)
bonus = models.CharField(max_length=255)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing related_name attribute on this ForeignKey field. Checklist item #3 requires adding related_name to all ForeignKey fields to enable accessing related models from the 'many' side. Add related_name='skills'.

race = models.ForeignKey(
Race,
Comment on lines +12 to +13
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #5: Use .get() method instead of direct dictionary access. Replace players_data[player] with players_data.get(player) to avoid potential KeyError.

on_delete=models.CASCADE,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #5: Use .get() method for nested dictionary access. The JSON structure may not guarantee these keys exist.

related_name="skills"
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #5: Use .get() method for nested dictionary access to avoid KeyError if structure varies.


Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using direct dictionary access [] instead of .get() method. Per checklist item #5, use .get() for safer access to dictionary keys.


Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using direct dictionary access [] instead of .get() method. Per checklist item #5, use .get() for safer access to dictionary keys.

class Guild(models.Model):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using direct dictionary access [] instead of .get() method. Per checklist item #5, use .get() for safer access to dictionary keys.

name = models.CharField(max_length=255, unique=True)
description = models.TextField(null=True)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using direct dictionary access [] instead of .get() method. Per checklist item #5, use .get() for safer access to dictionary keys.


Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using direct dictionary access [] instead of .get() method. Per checklist item #5, use .get() for safer access to dictionary keys.


class Player(models.Model):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #5: Use .get() method for nested dictionary access instead of players_data[player].

nickname = models.CharField(max_length=255, unique=True)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #5: Use .get() method for nested dictionary access instead of players_data[player].

email = models.EmailField(max_length=255)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using try/except TypeError to handle missing guild data is fragile. Per checklist item #5, use .get() method instead: guild_data = players_data[player].get("guild").

bio = models.CharField(max_length=255)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing related_name attribute on this ForeignKey field. Checklist item #3 requires adding related_name to all ForeignKey fields. Add related_name='players'.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per checklist item #5, use .get() method for safe dictionary access instead of [].

race = models.ForeignKey(
Race,
on_delete=models.CASCADE,
related_name="players"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #5: Use .get() method for dictionary access instead of players_data[player].

)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #5: Use .get() method for dictionary access instead of players_data[player].

guild = models.ForeignKey(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates checklist item #5: Use .get() method for dictionary access instead of players_data[player].

Guild,
on_delete=models.SET_NULL,
null=True,
related_name="players"
)
created_at = models.DateTimeField(auto_now_add=True)
31 changes: 30 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,39 @@
import init_django_orm # noqa: F401
import json

from db.models import Race, Skill, Player, Guild


def main() -> None:
pass
with open("players.json", "r") as player_file:
players_data = json.load(player_file)

for player in players_data.keys():
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ForeignKey is missing related_name. According to checklist item #3, you must add related_name to ForeignKey fields to allow access to related models on the Many side (e.g., related_name='skills').

race_obj, created = Race.objects.get_or_create(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() for safe dictionary access (e.g., players_data[player].get("race", {})).

name=players_data[player]["race"]["name"],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() for safe dictionary access.

Comment on lines +12 to +13
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checklist item #5 violation: Use .get() method for dictionary access instead of direct [] access. Replace players_data[player]["race"]["name"] with players_data[player].get("race") and access nested keys safely.

description=players_data[player]["race"]["description"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checklist item #5 violation: Use .get() method for dictionary access instead of direct [] access.

)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() for safe dictionary access.

for skill in players_data[player]["race"]["skills"]:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checklist item #5 violation: Use .get() method for dictionary access instead of direct [] access.

Skill.objects.get_or_create(
name=skill["name"],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checklist item #5 violation: Use .get() method for dictionary access instead of direct [] access.

bonus=skill["bonus"],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checklist item #5 violation: Use .get() method for dictionary access instead of direct [] access.

race_id=race_obj.pk
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The guild handling logic is problematic. If players_data[player].get("guild") returns None, the code catches TypeError but guild_obj remains undefined, causing a NameError on line 33. Replace the try/except block with proper conditional logic: guild_data = players_data[player].get("guild") followed by if guild_data: check.

guild_data = players_data[player].get("guild")
if guild_data:
guild_obj, created = Guild.objects.get_or_create(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ForeignKey is missing related_name. According to checklist item #3, you must add related_name to ForeignKey fields to allow access to related models on the Many side (e.g., related_name='players').

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() for safe dictionary access.

name=players_data[player]["guild"]["name"],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ForeignKey is missing related_name. According to checklist item #3, you must add related_name to ForeignKey fields to allow access to related models on the Many side (e.g., related_name='players').

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checklist item #5 violation: Use .get() method for dictionary access instead of direct [] access.

description=players_data[player]["guild"]["description"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checklist item #5 violation: Use .get() method for dictionary access instead of direct [] access.

)
else:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical bug: When guild_data is None, guild_obj is never defined, so guild_obj.pk = None causes a NameError. Define guild_obj with guild_id=None in the else branch instead.

guild_obj.pk = None
Player.objects.get_or_create(
nickname=player,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() for safe dictionary access.

email=players_data[player]["email"],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() for safe dictionary access.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checklist item #5 violation: Use .get() method for dictionary access instead of direct [] access.

bio=players_data[player]["bio"],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checklist item #5 violation: Use .get() method for dictionary access instead of direct [] access.

race_id=race_obj.pk,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses direct dictionary access [] instead of the safer .get() method. According to checklist item #5, use .get() for safe dictionary access.

guild_id=guild_obj.pk
)


if __name__ == "__main__":
Expand Down
Loading