我正在编写的应用程序包含一个用于创建事件的管道。 Event
由一类用户提出,然后由管理员批准和编辑。对我来说问题是有一个Event
,ScoredEvent
的子类,管理员应该可以在运行中指定。这会添加ScoredEvent.competition
外键并覆盖Event.participants
,以便将它们放入包含每个参与者的关联分数的表中。
理想情况下,普通用户创建一个仅包含名称和简短描述的事件(通过限制非管理员CreateEventForm上的字段可以轻松完成),然后管理员可以返回并填写其他字段正在批准这项活动。
我遇到的问题是我不知道管理员在编辑时如何将Event
更改为审核表单视图中的ScoredEvent
或如何实现这一目标。我对该页面的看法是一个编辑视图,其中有一个标记为“Tie To Competition”的复选框,选中后,将允许管理员选择一个比赛,然后将该事件保存为ScoredEvent
。如果未选中该框,则该事件将以Event
生效。
应该在哪里处理?我的直觉是我应该在模板中的forms.py或其他东西做一些特别的事情,但我不知道应该从哪里开始。
class Event(models.Model):
"""Representation of any community event"""
name = models.CharField(max_length=50, unique_for_date="start_datetime")
slug = models.SlugField(max_length=57) # length +7 for datestamp
description = models.TextField()
location = models.CharField(max_length=100, blank=True)
start_datetime = models.DateTimeField('Start', blank=True)
end_datetime = models.DateTimeField('End', blank=True)
participants = models.ManyToManyField(Participant)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name)+'-'+datetime.now().strftime("%d%m%y")
super(Event, self).save(*args, **kwargs)
def __unicode__(self):
if self.start_datetime:
return "%s (%s)" % (self.name, self.start_datetime.date())
else:
return self.name
class ScoredEvent(Event):
"""Representation of an event that is tied to a competition"""
competition = models.ForeignKey(Competition)
participants = models.ManyToManyField(Participant, through="ScoredParticipant")
def is_scored(self):
"""Returns true if any of the participants has a score, else returns false"""
for participant in self.participants.objects.all():
if participant.score != 0:
return False
return True
class ScoredPartcipant(models.Model):
"""Participant and associated score for an event"""
participant = models.ForeignKey(Participant)
event = models.ForeignKey(ScoredEvent)
score = models.IntegerField(default=0)
答案 0 :(得分:0)
覆盖get_queryset
,并根据是否发布其中一个字段而有所不同:
def get_queryset(self):
if self.request.POST.has_key('competition'):
return ScoredEvent.objects.all()
else:
return super(MyView, self).get_queryset()
所以,只是为了解释一下:你会使用你提到的“Tie to Competition”选项通过Javascript向表单添加一个字段。然后,如果在POST中发送该字段,则会切换为使用ScoredEvent
。
如果您想根据当前对象的内容自动切换,则需要覆盖get_object
。有点像:
def get_object(self, queryset=None):
obj = super(MyView, self).get_object(queryset=queryset)
try:
return ScoredEvent.objects.get(pk=obj.pk)
except ScoredEvent.DoesNotExist:
return obj
其中基本上尝试再次查找对象,就像它是ScoredEvent
一样,如果找到一个,则返回该版本,而不是Event
。
您也可能需要同样覆盖get_form_class
,以确保ScoredEvent
如果是ScoredEvent
或正在成为ScoredEvent
则验证为from django.forms import models as model_forms
def get_form_class(self):
if isinstance(self.object, ScoredEvent):
return model_forms.modelform_factory(ScoredEvent, ScoredEventForm)
else:
return super(MyView, self).get_form_class()
:
{{1}}