2010-05-29 169 views
3

我正在編寫一個測試「成績簿」應用程序。 models.py文件如下所示。django中的強制性只讀字段

class Student(models.Model): 
    name = models.CharField(max_length=50) 
    parent = models.CharField(max_length=50) 
    def __unicode__(self): 
     return self.name 

class Grade(models.Model): 
    studentId = models.ForeignKey(Student) 
    finalGrade = models.CharField(max_length=3) 

我希望能夠改變最終成績爲幾個學生在modelformset但現在我只是在時間試圖一名學生。我也試圖爲它創建一個表單,將學生名稱顯示爲無法更改的字段,唯一可以在此處修改的是finalGrade。所以我用這個技巧讓studentId只讀。

class GradeROForm(ModelForm): 
    studentId = forms.ModelChoiceField(queryset=Student.objects.all()) 
    def __init__(self, *args, **kwargs): 
     super(GradeROForm,self).__init__(*args, **kwargs) 
     instance = getattr(self, 'instance', None) 
     if instance and instance.id: 
      self.fields['studentId'].widget.attrs['disabled']='disabled' 
    def clean_studentId(self): 
     instance = getattr(self,'instance',None) 
     if instance: 
      return instance.studentId 
     else: 
      return self.cleaned_data.get('studentId',None) 
    class Meta: 
     model=Grade 

這是我的觀點:

def modifyGrade(request,student): 
    student = Student.objects.get(name=student) 
    mygrade = Grade.objects.get(studentId=student) 
    if request.method == "POST": 
     myform = GradeROForm(data=request.POST, instance=mygrade) 
     if myform.is_valid(): 
      grade = myform.save() 
      info = "successfully updated %s" % grade.studentId 
    else: 
     myform=GradeROForm(instance=mygrade) 
    return render_to_response('grades/modifyGrade.html',locals()) 

這就像我希望顯示的形式,但是當我點擊「提交」,我得到了學生的實地告訴我,這個領域是一個表單驗證錯誤需要。我猜測,由於該字段是「禁用的」,因此該值不會在POST中報告,並且由於我未知的原因,該實例未被用於其位置。

我是一名新的Django/Python程序員,但在其他語言方面頗有經驗。我無法相信我在第一個重要的django應用程序中偶然發現了這樣一個難以解決的問題。我想我必須錯過一些東西。有任何想法嗎?

+0

看一看的答案[「在Django的形式,如何使一個外地只讀(或禁用),以便它無法編輯?「](http://stackoverflow.com/questions/324477/in-a-django-form-how-to-make-a-field-readonly-or-disabled-所以,它不能)我認爲與那些你將能夠解決你的問題。 – 2010-05-29 02:17:22

+0

謝謝菲利克斯。我之前就看到了這一點,但無法讓它正常工作。看到我的評論下面有關添加「required = False」這似乎是最後的障礙。 – jamida 2010-05-29 17:15:54

回答

6

您應該執行:

self.fields['studentId'].widget.attrs['readonly'] = True 

,並且確保不覆蓋上回發的值。

此外,如果仍然有需要的領域的問題,你可以做你的ModelForm如下:

studentID = forms.CharField(label="A label", help_text="Student ID", required=False) 
+1

這個伎倆!看起來醜陋,但可行。無論如何,這是一個原型。儘管我有一件事讓我感到驚訝。我必須添加「required = False」,即使這實際上是模型級別的必需字段。在我的自定義清理例程之前,studentId字段沒有被髮送回POST響應,並且沒有「required = False」語句表單驗證失敗。但顯然,在「required = false」的情況下,我的Clean例程有機會運行並重置正確的studentId信息。 – jamida 2010-05-29 17:15:12

+0

其實還有一個小問題。我在提交表單時返回「只讀字段」爲空。它仍然有效,可能是因爲修改了clean(),但它很尷尬。有什麼想法嗎? – jamida 2010-05-29 20:09:23

+0

您可以重新填充檢索模型中的表單值嗎? – 2010-05-30 10:33:01