2012-08-09 71 views
0

我正在編寫的應用程序包含一個用於創建事件的管道。 Event由一類用戶提出,然後由管理員批准和編輯。對我來說,問題是有一個Event,ScoredEvent的子類,管理員應該能夠即時指定它。這將添加一個ScoredEvent.competition外鍵,並覆蓋Event.participants,使其通過包含每個參與者的關聯分數的表格。有沒有辦法在Django中動態更改UpdateView中使用的模型?

理想的情況下,普通用戶創建一個僅包含名稱和一個簡短的說明(很容易的通過限制非管理員CreateEventForm領域做)的事件,則管理員可以回去,並填寫在其他領域他們正在批准這一事件。

我打的問題是我不知道怎麼會是可能的管理員在審批表單視圖時,他們編輯它,或者如何使這種情況發生改變EventScoredEvent。我對該頁面的看法是一個編輯視圖,帶有一個標有「與競爭對手聯繫」的複選框,選中該選項後,管理員可以選擇一個競賽,然後將該事件保存爲ScoredEvent。如果該框未被檢查,則該事件將繼續其作爲Event的生命。

這應該在哪裏處理?我的直覺是,我應該在Templates.py或Templates中的某些內容中做些特別的事情,但我不知道該從哪裏開始。

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

你需要一個外鍵從'ScoredEvent'正常'事件「,然後管理員創建一個'ScoredEvent'鏈接到正常的'Event',用戶填充。 – 2012-08-09 18:47:08

回答

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() 

所以,只是爲了更好地說明一點:你可以使用你所提到的增加你的「領帶大賽」選項一個字段通過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() 
+0

因此,如果我正確地理解了這一點,那麼事件仍然是一個「事件」,除非管理員指定了競爭對手fk,在這種情況下它將成爲「ScoredEvent」。那是對的嗎? – Kapura 2012-08-09 19:13:08

+0

請參閱上面的更新。 – 2012-08-09 19:41:20

相關問題