2012-07-11 48 views
1

我希望ForeignKey的每個實例具有不同的默認值,具體取決於它在父模型中的屬性。做的時候如何爲外鍵中的特定字段指定默認的外地字段值?

class Day(models.Model): 
    date = models.DateField(unique=True) 
    manager_shift = models.ForeignKey('Shift') # Shift.shift_type should be "M" 
    lead_shift = models.ForeignKey('Shift') # Shift.shift_type should be "L" 
    early_day_shift = models.ForeignKey('Shift') # Shift.shift_type should be "ED" 
    late_day_shift = models.ForeignKey('Shift') # Shift.shift_type should be "LD" 
    swing_shift = models.ForeignKey('Shift') # Shift.shift_type should be "SW" 
    early_evening_shift = models.ForeignKey('Shift') # Shift.shift_type should be "EM" 
    late_evening_shift = models.ForeignKey('Shift') # Shift.shift_type should be "LM" 

class Shift(models.Model): 
    user = models.ForeignKey('User', limit_choices_to={'is_staff': True}, blank=False) 
    shift_type = models.CharField(max_length=2, choices=SHIFT_TYPE_CHOICES, blank=False) 

SHIFT_TYPE_CHOICES = { 
    ('M', 'Manager'), 
    ('L', 'Lead'), 
    ('ED', 'Early Day'), 
    ('LD', 'Early Day'), 
    ('SW', 'Swing'), 
    ('EM', 'Early Evening'), 
    ('LM', 'Late Evening'), 
} 

在這種情況下,

所以:

的插圖可能使這更清楚

Day.manager_shift = Shift() 

Day.manager_shift.shift_type應該是 「M」 自動

回答

1

我不相信有這樣做的內置方式,也不應該有b即如果你做了,會發生什麼:

>>> my_shift = Shift() 
>>> Day.manager_shift = my_shift 
>>> Day.lead_shift = my_shift 
>>> my_shift.shift_type 
??? 

一個更好的選擇將是壓倒一切的Daysave方法檢查所保存的對象和各個領域:1)如果沒有shift_type,加上正確的; b)如果出現換班時間,但出現錯誤,提出錯誤(不是最乾淨的解決方案,但我不知道更好的)。

更新:我只是read編輯:和羅漢也指出),您可以給一個默認值到ForeignKey,但你應該在一個函數的形式,這樣做的:

def default_type(type): 
    temp = [type] # Necessary because Python can't handle closures properly sometimes 
    def closure(): 
     return Shift.objects.get(shift_type=temp[0]) 
    return closure 

class Day(models.Model): 
    date = models.DateField(unique=True) 
    manager_shift = models.ForeignKey('Shift', default=default_type('M')) 
+0

我明白你的意思,但以同樣的方式你可以爲未指定值的模型的字段指定默認值,對於我來說,你可以爲正在創建新實例的字段指定默認的外部字段值。 – Ben174 2012-07-11 05:18:10

+0

是的,但你會用什麼作爲價值?唯一對我有意義的是使用另一個模型的主鍵(因爲這是唯一可以唯一標識該模型中的一行)。 – mgibsonbr 2012-07-11 05:21:05

1

你可以有默認值作爲可調用的,所以你可以這樣做:

def get_m_shift(): 
    return Shift.objects.get(shitf_type='M') 

    class Day(models.Model): 
     date = models.DateField(unique=True) 
     manager_shift = models.ForeignKey('Shift', default=get_m_shift) 

我想你必須編寫函數來獲取每個班次類型。我不確定默認的可調用參數。

+0

儘管您無法傳遞參數,但您可以讓其他函數返回可調用對象(即創建一個閉包)。以我的答案爲例。 – mgibsonbr 2012-07-11 05:18:52

+0

這是不是我想要的。 Shift對象尚不存在。我希望創建的新Shift對象具有該「M」值(如果它們被分配給manager_shift屬性)。我期望看到的代碼是這樣的:manager_shift = models.ForeignKey('Shift',shift.shift_type =「M」) – Ben174 2012-07-11 05:25:53

+0

@ Ben174如果你想創建它,你需要獲得_User_實例來創建_Shift_,是可用的嗎? – Rohan 2012-07-11 05:29:33

1

爲什麼你有一個單獨的'日'模型?

SHIFT_TYPE_CHOICES = { 
    ('M', 'Manager'), 
    ('L', 'Lead'), 
    ('ED', 'Early Day'), 
    ('LD', 'Early Day'), 
    ('SW', 'Swing'), 
    ('EM', 'Early Evening'), 
    ('LM', 'Late Evening'), 
} 

class Shift(models.Model): 
    user = models.ForeignKey('User', 
          limit_choices_to={'is_staff': True}, 
          blank=False) 
    shift_type = models.CharField(max_length=2, 
            choices=SHIFT_TYPE_CHOICES, 
            blank=False) 
    shift_date = models.DateField() 

    class Meta: 
     unique_together = (('shift_date','shift_user','shift_type'),) 

這樣可以防止同一用戶在同一日期發生重複的班次,只有一種班次類型和用戶的組合。您可以根據自己的需求進行調整。因此,如果您需要在同一日期多次輪班,請刪除shift_datedocumentation for unique_together解釋了這是如何工作的。

現在,找出誰是在特定的一天店長:

for s in Shift.objects.filter(shift_type='M', 
           shift_date=datetime.datetime.today()): 
    print s.user 

或者打印天整個陣容:

for s in Shift.objects.filter(shift_date=datetime.datetime.today()): 
    print "%s: %s\n" % (s.get_shift_type_display(),s.user) 
+0

我同意Day對象完全沒有意義。但是這個對象模型已經在視圖中被大量使用。這將需要一些重大的重構來刪除它。我繼承了這個項目。 – Ben174 2012-07-11 05:40:35

相關問題