我在模型中为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
这是一个简单的日历应用程序,我的想法是我有一个人们可以在指定的群组中注册的活动。所以我希望能够创建事件并同时创建一些组,然后向组添加插槽。
我在Slot模型中有事件字段,因为我需要确保人们无法同时注册2个插槽,我还需要计算插槽数(事件模型中的字段)。我显然需要两个模型中的事件字段指向同一个事件,所以我认为我可以为Slot.event设置一个默认值。
随意提交任何变通方法,我可以轻松地重新设计我的应用程序。在此先感谢您的帮助。
编辑: 我会尝试更好地描述我的应用程序:它应该是一个在线游戏社区的日历(游戏是arma3)。我希望每个活动的参加人数不超过40人,但对于我们的游戏会议,我们需要等级。特别是我们将自己分成小组,每个小组都有不同的角色(团队领导,机枪手,步枪兵等)。我希望有一个日历,您可以在其中查看特定的活动详细信息,包括组和所有不同的插槽,并注册一个特定的插槽。我希望它澄清它。请原谅所有错误,英语不是我的第一语言。
我之前忘了提到它,但我是Django的绝对初学者,我在python 3.4上运行Django 1.7。使用lambda的解决方案似乎不起作用,这里是错误日志(抱歉没有缩进):
(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
答案 0 :(得分:3)
我遇到类似的问题,尝试在没有默认值的情况下向迁移添加外键。删除lambda表达式并将默认值设置为nullable(None),然后使用以下代码示例再次尝试。它对我来说很完美。
e.g:
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')
为了简单起见,我在模型上省略了非感兴趣的字段。我希望它可以帮助你。
答案 1 :(得分:0)
像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()
作为一个不相关的建议,不要使用原始用户模型。使用它的正确方法是documentation。
from django.conf import settings
from django.db import models
class Article(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL)
如果您将来需要使用其他用户模型,如果您这样做,您的应用就不会中断。
编辑:
我误解了几件事。似乎事件有几个组,组有几个插槽。现在,&#34;有几个&#34;可以用外键表示。
在这种情况下,组应该具有事件的外键,并且插槽应该具有组的外键。 您可以通过以下方式检查某个广告位的事件:
my_slot.group.event