Django - внешний ключ по умолчанию

у меня проблема с установкой значения по умолчанию для моего поля ForeignKey в модели. Вот мой код:

class Group(models.Model):
    name = models.CharField(max_length=50)
    event = models.ForeignKey(Event)

def __str__(self):
    return self.name

class Slot(models.Model):
    title = models.CharField(max_length=50,  blank = True)
    name = models.ForeignKey(SlotName)
    is_taken = models.BooleanField(default=False)
    usr = models.ForeignKey('auth.User', blank=True, null=True)
    group = models.ForeignKey(Group)
    event = models.ForeignKey(Event) #i would like to have something like "default=group.event" here 

    def __str__(self):
        return self.name.name

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

у меня есть поле событий в модели слота, потому что мне нужно убедиться, что люди не смогут подписаться на 2 слота в то же время, и мне также нужно рассчитать количество слотов (поле в модели событий). Мне, очевидно, нужно, чтобы поля событий в обеих моделях указывали на одно и то же событие, поэтому я подумал, что у меня может быть что-то вроде значения по умолчанию для моего слота.событие.

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

изменить: Я постараюсь лучше описать свое приложение: это должен быть календарь для сообщества онлайн-игр (игра arma3). Я ожидаю каждый мероприятии примут участие не более 40 человек, но для нашей игры нам нужны иерархии. В частности, мы делим себя на группы, в каждой группе разные роли(командир, пулеметчик, стрелок и др.).). Я хочу иметь календарь, в котором вы можете просматривать конкретные детали событий, включая группы и все различные слоты, и подписаться на один конкретный слот. Надеюсь, это все прояснит. Пожалуйста, простите все ошибки, английский не мой первый язык.

I забыл упомянуть об этом ранее, но я абсолютный новичок в Django и запускаю Django 1.7 на python 3.4. Решение с использованием лямбда, похоже, не работает, вот журнал ошибок (извините за отсутствие отступов):

(own)qwe@qwe:~/Projects/own/src$ python manage.py makemigrations
Migrations for 'cal':
0021_auto_20141202_1913.py:
- Remove field title from slot
- Alter field event on slot
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/qwe/Projects/own/lib/python3.4/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
File "/home/qwe/Projects/own/lib/python3.4/site-packages/django/core/management/__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/qwe/Projects/own/lib/python3.4/site-packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File "/home/qwe/Projects/own/lib/python3.4/site-packages/django/core/management/base.py", line 338, in execute
output = self.handle(*args, **options)
File "/home/qwe/Projects/own/lib/python3.4/site-packages/django/core/management/commands/makemigrations.py", line 124, in handle
self.write_migration_files(changes)
File "/home/qwe/Projects/own/lib/python3.4/site-packages/django/core/management/commands/makemigrations.py", line 152, in write_migration_files
migration_string = writer.as_string()
File "/home/qwe/Projects/own/lib/python3.4/site-packages/django/db/migrations/writer.py", line 129, in as_string
operation_string, operation_imports = OperationWriter(operation).serialize()
File "/home/qwe/Projects/own/lib/python3.4/site-packages/django/db/migrations/writer.py", line 86, in serialize
arg_string, arg_imports = MigrationWriter.serialize(arg_value)
File "/home/qwe/Projects/own/lib/python3.4/site-packages/django/db/migrations/writer.py", line 310, in serialize
return cls.serialize_deconstructed(path, args, kwargs)
File "/home/qwe/Projects/own/lib/python3.4/site-packages/django/db/migrations/writer.py", line 221, in serialize_deconstructed
arg_string, arg_imports = cls.serialize(arg)
File "/home/qwe/Projects/own/lib/python3.4/site-packages/django/db/migrations/writer.py", line 323, in serialize
raise ValueError("Cannot serialize function: lambda")
ValueError: Cannot serialize function: lambda

вот обновленный код(опять же, могут быть ошибки отступов, я не могу обойти эту систему кода здесь):

class Event(models.Model):
    author = models.CharField(max_length=200)
    title = models.CharField(max_length=200)
    details = models.TextField(max_length=5000)
    slots_no = models.PositiveIntegerField(default=0, editable=False)
    created_date = models.DateTimeField(
        auto_now=True)
    event_date = models.DateField(
        blank=True, null=True)
    event_time = models.TimeField(default='20:00')
    created_by = models.ForeignKey('auth.User')
    type = models.ForeignKey(EventType)


    def publish(self):
        self.save()

    def __str__(self):
        return self.title

class Group(models.Model):
    name = models.CharField(max_length=50)
    event = models.ForeignKey(Event)

    def __str__(self):
        return self.name


class Slot(models.Model):
    #title = models.CharField(max_length=50,  blank = True)
    name = models.ForeignKey(SlotName)
    is_taken = models.BooleanField(default=False)
    usr = models.ForeignKey('auth.User', blank=True, null=True)
    group = models.ForeignKey(Group)
    event = models.ForeignKey(Event)
    def __str__(self):
        return self.name.name

2 ответов


У меня была аналогичная проблема, пытаюсь добавить внешний ключ к миграции без значения по умолчанию. Удалите лямбда-выражение и пусть значение по умолчанию равно nullable (None) и повторите попытку со следующим образцом кода. Для меня это сработало идеально.

Эл.г:

from django.db import models                                                    


class Slot(models.Model):                                                       
    event = models.ForeignKey('Event', null=True)                               
    group = models.ForeignKey('Group', null=True)                               
    def save(self, *args, **kwargs):                                            
        if(self.group is not None and self.group.event is not None):            
            self.event = self.group.event                                       
        super(Slot, self).save(*args, **kwargs)                                 

class Event(models.Model):                                                      
    name = models.CharField(max_length=100)                                     

class Group(models.Model):                                                      
    name  = models.CharField(max_length=100)                                    
    event = models.ForeignKey('Event')  

Я опустил не интересные поля на моделях для простоты. Надеюсь, это поможет вам.


что-то вроде того, что daniph предложил должно работать:

event = models.ForeignKey(Event, default=lambda: self.group.event if self.group else None)

теперь, если я вас понимаю, события создаются для определенных групп, и у этих событий есть слоты, которые пользователи могут использовать для регистрации события.

Я бы поступил так:

class Event(models.Model):
    group = models.ForeignKey(Group)

class Group(models.Model):
    name = models.CharField(max_length=50)

class Slot(models.Model):
    title = models.CharField(max_length=50,  blank = True)
    name = models.ForeignKey(SlotName)
    is_taken = models.BooleanField(default=False)
    usr = models.ForeignKey('auth.User', blank=True, null=True)
    event = models.ForeignKey(Event)

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

вы можете изменить запрос им например:

слоты для моего случая:

my_event.slot_set.all()

события для моей группы:

my_group.event_set.all()

в качестве несвязанного совета не используйте модель raw user. Правильный способ его использования-в документация.

from django.conf import settings
from django.db import models

class Article(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL)

Если вам нужно использовать другую модель пользователя в будущем, ваше приложение не сломается, если вы сделаете это таким образом.

Edit:

Я не понял пару вещей. Кажется, события несколько групп и групп несколько игровые автоматы. Теперь "иметь несколько" можно представить с помощью внешнего ключа.

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

my_slot.group.event