Skip to content
Open

Develop #1732

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
52 changes: 52 additions & 0 deletions db/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Generated by Django 6.0.5 on 2026-05-20 12:53

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


class Migration(migrations.Migration):

initial = True

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 violates checklist item #3: 'add related_name to all ForeignKey fields'. Consider adding related_name to access related models from the Race side.

]

operations = [
migrations.CreateModel(
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.

Migration lacks related_name='players' on guild ForeignKey - needs regeneration to match updated model.

('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True)),
('description', models.TextField(null=True)),
],
),
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.

This violates checklist item #3: 'add related_name to all ForeignKey fields'. Consider adding related_name to access related models from the Race side.

name='Race',
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: 'add related_name to all ForeignKey fields'. Consider adding related_name to access related models from the Guild side.

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.

This violates checklist item #6: 'Use auto_now_add=True for created_at to record the time of creation'. Currently using auto_now=True which updates on every save, not just creation.

('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Use .get() method instead of direct bracket access. This matches checklist item #5 requirement for safe dictionary access.

('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.

Use .get() method instead of direct bracket access for consistency with checklist item #5.

('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.

Use .get() method instead of direct bracket access for consistency with checklist item #5.

],
),
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.

Migration uses auto_now=True but models.py now correctly uses auto_now_add=True. This migration needs to be regenerated to match the updated model.

('created_at', models.DateTimeField(auto_now=True)),
('guild', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, 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.

ForeignKey lacks related_name='players' - needs regeneration to match updated model.

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

Choose a reason for hiding this comment

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

ForeignKey lacks related_name='players' - needs regeneration to match updated model.

],
),
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)),
('race', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='db.race')),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ForeignKey lacks related_name='skills' - needs regeneration to match updated model.

],
),
]
19 changes: 19 additions & 0 deletions db/migrations/0002_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-21 08:41

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


class Migration(migrations.Migration):

dependencies = [
('db', '0001_initial'),
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 to safely access dictionary keys. For example: race_data = player.get("race") and then check if it's truthy before processing.

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 dictionary key access. Direct access like player_data["race"] assumes the key always exists. Consider using .get() for safer access patterns.

]
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 #3 violation: ForeignKey fields must include related_name parameter. Add related_name to all ForeignKey fields to allow reverse access from related models.


operations = [
migrations.AlterField(
model_name='player',
name='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.

Checklist item #5 violation: Use .get() method for safer dictionary access since we're not guaranteed that 'skills' key exists in race_data.

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 migration is missing the related_name='players' attribute on the guild ForeignKey. After adding related_name to models, migrations need to be regenerated as per checklist item #2.

),
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 bracket access race_data["description"]. Per checklist item #5, use .get() method instead: race_data.get("description") to avoid potential KeyError.

]
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Generated by Django 6.0.5 on 2026-05-21 16:02

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


class Migration(migrations.Migration):

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

operations = [
migrations.AlterField(
model_name='player',
name='created_at',
field=models.DateTimeField(auto_now_add=True),
),
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 parameter on this ForeignKey. Checklist item #3 requires adding related_name to all ForeignKey fields.

race = 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.

Use .get() method for dictionary access instead of direct bracket access to avoid KeyError when 'description' key is missing

Race,
on_delete=models.CASCADE,
related_name="skills"
)


class Guild(models.Model):
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.

Use .get() method for dictionary access instead of direct bracket access to avoid KeyError when 'description' key is missing


class Player(models.Model):
nickname = models.CharField(max_length=255, unique=True)
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.

Use .get() method for dictionary access instead of direct bracket access to avoid KeyError when 'email' key is missing

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 parameter on this ForeignKey. Checklist item #3 requires adding related_name to all ForeignKey fields.

race = models.ForeignKey(
Race,
on_delete=models.CASCADE,
related_name="players"
)
guild = models.ForeignKey(
Guild,
on_delete=models.SET_NULL,
null=True,
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.

Migration file 0001_initial.py contains outdated model definitions. The Player model's created_at field uses auto_now=True (line 37) instead of auto_now_add=True, and ForeignKey fields lack related_name parameters. When tests run migrations from scratch, this will fail. Regenerate migrations after making model corrections.

)
created_at = models.DateTimeField(auto_now_add=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.

Migration file 0001_initial.py - Player.guild ForeignKey uses CASCADE (line 39) instead of SET_NULL. The 0002 migration fixes this, but 0001 still has the incorrect value for fresh installs.

34 changes: 32 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,40 @@
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", encoding="utf-8") as file:
players_data = json.load(file)

for nickname, player_data in players_data.items():
race_data = player_data.get("race")
race, _ = Race.objects.get_or_create(
name=race_data.get("name"),
defaults={"description": race_data["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.

Use .get() method for dictionary access instead of direct bracket notation to avoid potential KeyError

)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Use .get() method for dictionary access instead of direct bracket notation to avoid potential KeyError

for skill_data in race_data["skills"]:
Skill.objects.get_or_create(
name=skill_data.get("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.

Use .get() method for dictionary access instead of direct bracket notation to avoid potential KeyError

defaults={"bonus": skill_data["bonus"], "race": race},
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Use .get() method for dictionary access instead of direct bracket notation to avoid potential KeyError. Change to: guild_data = player_data.get("guild")

guild_data = player_data["guild"]
guild = None
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 #3 violation: This ForeignKey is missing the required related_name parameter. Add related_name='players' to enable access to related players from the Guild model.

if guild_data is not None:
guild, _ = Guild.objects.get_or_create(
name=guild_data.get("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.

Use .get() method for dictionary access instead of direct bracket notation to avoid potential KeyError

defaults={"description": guild_data["description"]},
)

Player.objects.create(
nickname=nickname,
email=player_data.get("email"),
bio=player_data.get("bio"),
race=race,
guild=guild,
)


if __name__ == "__main__":
Expand Down
Loading