Django модели "один ко многим" - Как создать "многие", когда "один" создан?

Здесь много вопросов на эту тему, но, насколько я могу судить, многие из них довольно старые, и я не нашел ни одного, который помог бы мне понять мой случай использования. Я думаю, что я хочу рассматривать сигналы, но я не совсем понимаю, что именно я должен делать с точки зрения шаблонов Django и лучших практик.

Вот мой код модели:

from django.db import models
from django.db.models.fields import SlugField, TextField
from django.utils import timezone


# Hexes have Terrains, which impart intrinsic properties, like base speed and .png image
# They're NOT 1:1 with Hexes IE) You might want Slow and Normal Grasslands with the same image
class Terrain(models.Model):
    FAST = 'F'
    NORMAL = 'N'
    SLOW = 'S'
    SPEED_CHOICES = [
        (FAST, 'Fast'),
        (NORMAL, 'Normal'),
        (SLOW, 'Slow'),
    ]
    name = models.CharField(max_length=64)
    speed = models.CharField(max_length=6, choices=SPEED_CHOICES, default=NORMAL)
    image = models.ImageField(upload_to='images/', blank=True)

    def __str__(self):
        return self.name

# Grids establish the dimensions of a HexMap. Grids may be used in many HexMaps
class Grid(models.Model):
    name = models.CharField(max_length=64)
    size = models.IntegerField(default=72)
    num_rows = models.IntegerField(default=10)
    num_cols= models.IntegerField(default=10)

    def __str__(self):
        return self.name

# Hexes represent the "tiles" on a Grid. A single Hex may appear in many Grids
class Hex(models.Model):
    name = models.CharField(max_length=64, blank=True, null=True)
    terrain = models.ForeignKey(Terrain, on_delete=models.CASCADE)
    grids = models.ManyToManyField(Grid)

    def __str__(self):
        return self.id

    class Meta:
        verbose_name_plural = "Hexes"

# Locations are coordinal points on a HexMap. They may contain many Annotations
class Location(models.Model):
    # HexMap Name + row + col, for a consistent way to ID locations
    name = models.CharField(max_length=64, blank=True, null=True)
    friendly_name = models.CharField(max_length=64, blank=True, null=False)
    # TODO constrain these to the sizes specified in the grids? Sane defaults?
    row = models.PositiveIntegerField()
    col = models.PositiveIntegerField()

# Authors create Annotations
# TODO create Players and make Authors extend it so we can do rights and perms
class Author(models.Model):
    first_name = models.CharField(max_length=64, blank=False, null=False)
    last_name = models.CharField(max_length=64, blank=False, null=False)
    join_date = timezone.now()

    def __str__(self):
        return self.first_name + " " + self.last_name


# Annotations are entries created by Authors. A location may have many Annotations
class Annotation(models.Model):
    name = models.CharField(max_length=64, blank=False, null=False)
    pubdate = join_date = timezone.now()
    content = TextField()

# Hexmaps put it all together and allow fetching of Locations by (r,c) coords
class HexMap(models.Model):
    name = models.CharField(max_length=64, blank=True, null=True)
    rows = {}
    cols = {}
    #TODO - how do I create grid.num_rows * grid.num_cols locations and put them into the dicts?

Возможно, я допускаю массу ошибок, поскольку я не работал в Django почти десять лет. Любая конструктивная обратная связь приветствуется в комментариях. Большинство связей не закодированы, так как я не уверен, как они должны выглядеть.

Мой конкретный вопрос, однако, связан с объектами HexMap и Location. Когда создается HexMap, я хочу создать набор пустых Locations со значением имени по умолчанию, соответствующим соглашению об именовании, например HexMap.name + row + col и заполнить ими dicts row{} и col{} новой HexMap.

Моя интуиция подсказывает, что для создания Hexmap требуется Grid, поэтому я мог бы создать вложенный цикл внутри HexMap с grid.num_rows в качестве внешнего цикла и num_cols в качестве внутреннего цикла. Каждая итерация внутреннего цикла создает строку Locations как dict. Каждая итерация внешнего цикла добавляет этот ряд в дикту rows{}. Я не уверен в том, как получить grid.num_rows и grid.num_cols, если HexMap еще не создана и не имеет связанной с ней сетки.

Является ли это хоть сколько-нибудь близким к правильному способу сделать это в Django, или я сбился с пути? Многие ответы и онлайн-учебники, кажется, указывают на то, что мне нужно смотреть на сигналы, но я просто не совсем понимаю, так это или нет. Кроме того, если да, то мне бы не помешало просмотреть несколько похожих примеров. Документация по Django великолепна и полезна, но когда вы "новичок" во всем этом, может быть трудно разобрать и принять примеры.

Нашел этот вопрос , который я действительно должен был задать в первую очередь. Хотя ему уже несколько лет, я думаю, что это все еще правильный ответ, и он помог направить меня к соответствующей документации. Все еще не уверен, каким будет мой следующий шаг, думаю, что мне нужны вменяемые значения по умолчанию и переопределение метода сохранения, чтобы использовать их, если экземпляры других полей еще не существуют. Я все еще работаю над тем, есть ли у меня обоснованный сценарий использования сигналов. Я думаю, что в конечном итоге это произойдет, когда я добавлю больше приложений в проект и действия в этих приложениях должны будут взаимодействовать с моделями в этом приложении.

Вернуться на верх