2010-05-28 2 views
4

일부 장고 기능을 확인하기 위해 작성중인 테스트 앱에 문제가 있습니다. 테스트 응용 프로그램은 현재 Alex Gaynor의 읽기 전용 필드 기능을 사용하는 작은 "성적 북"응용 프로그램입니다. http://lazypython.blogspot.com/2008/12/building-read-only-field-in-django.htmlDjango 양식 (읽기 전용 입력란/위젯)에서 이상한 동작

관련된 두 가지 문제점이 있습니다. 첫째, 아래 2 줄의 설명을 덧붙일 때 :

#  myform = GradeForm(data=request.POST, instance=mygrade) 
     myform = GradeROForm(data=request.POST, instance=mygrade) 

학생용 입력란이 변경 될 수 있다는 것을 제외하고는 예상대로 작동합니다.

의견이 표시된 경우 "studentId"필드는 숫자 (이름, 문제 1 아님)로 표시되며 제출을 누르면 studentId가 Student 인스턴스 여야한다는 오류가 표시됩니다.

이 문제를 해결하는 방법에 관해서는 분실했습니다. 알렉스 게이너의 코드에 집착하지 않아. 모든 코드가 작동합니다. 필자는 Python과 Django에 비교적 익숙하기 때문에 "읽기 전용 영역을 만드는 것이 쉽다"라는 웹 사이트에서 본 힌트는 여전히 저를 초월합니다.

// models.py

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) 

# testbed.grades.readonly is alex gaynor's code 
from testbed.grades.readonly import ReadOnlyField 
class GradeROForm(ModelForm): 
    studentId = ReadOnlyField() 
    class Meta: 
     model=Grade 

class GradeForm(ModelForm): 
    class Meta: 
     model=Grade 

// views.py

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

// 템플릿

<p>{{ info }}</p> 
<form method="POST" action=""> 
<table> 
{{ myform.as_table }} 
</table> 
<input type="submit" value="Submit"> 
</form> 

// 알렉스 게이너의 코드

from django import forms 
from django.utils.html import escape 
from django.utils.safestring import mark_safe 

from django.forms.util import flatatt 
class ReadOnlyWidget(forms.Widget): 
    def render(self, name, value, attrs): 
     final_attrs = self.build_attrs(attrs, name=name) 
     if hasattr(self, 'initial'): 
      value = self.initial 
     return mark_safe("<span %s>%s</span>" % (flatatt(final_attrs), escape(value) or '')) 

    def _has_changed(self, initial, data): 
     return False 

class ReadOnlyField(forms.FileField): 
    widget = ReadOnlyWidget 
    def __init__(self, widget=None, label=None, initial=None, help_text=None): 
     forms.Field.__init__(self, label=label, initial=initial, 
      help_text=help_text, widget=widget) 

    def clean(self, value, initial): 
     self.widget.initial = initial 
     return initial 

답변

3

장고 1.2 (일주일에 대해 발표하고 전 반) 읽기 전용 지원 상자 밖으로 관리자에 대한 필드 :

http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields

나는 그 새로운 기능을 확장하는 것이 얼마나 어려운 확실하지 않다 귀하의 사이트에 표시 할 수있는 ModelForm과 같은 것으로하지만 Alex (우수하지만 날짜가 기입 된) 코드보다 더 최신 시점의 역할을합니다.

+0

내 코드는 결국 userlogin 페이지 뒤에 있지만 관리자 시스템의 모든 기능을 사용하는 데는 관심이 없습니다. ModelAdmin은 일반적인 Admin 프레임 워크 외부에서 사용할 수 있습니까? 어쨌든, 나는 적어도 장고의 코드를보고 알렉스의 코드를 내 목적대로 "업데이트"할 수 있는지 알아볼 것입니다. – jamida

5

ReadOnlyField에 신경 쓰지 마십시오. 대신 위젯을 사용하십시오.

여기에 제가 정기적으로 사용하는 것이 있습니다.

class ReadOnlyWidget(forms.Widget): 

    def __init__(self, original_value, display_value): 
     self.original_value = original_value 
     self.display_value = display_value 
     super(ReadOnlyWidget, self).__init__() 

    def _has_changed(self, initial, data): 
     return False 

    def render(self, name, value, attrs=None): 
     if self.display_value is not None: 
      return unicode(self.display_value) 
     return unicode(self.original_value) 

    def value_from_datadict(self, data, files, name): 
     return self.original_value 

CharField와 함께 사용하십시오.

+0

나는 이것에 대해별로 행운이 없다. 나는 그것을 올바르게 사용하고 있다고 생각하지 않는다. 나는 계속 "TypeError : __init __()는 3 개의 인수 (주어진 1 개)를 취합니다". 나는 ROForm에서 studentId를 "forms.CharField"가되도록 "widget = ReadOnlyWidget"으로 변경하려고합니다. – jamida

+1

CharField가 아닌'ModelChoiceField' 여야합니다. 그러나이 도구 대신 Alex의 위젯을 사용하십시오.이 도구는'__init__' 메서드에서 이상한 요구 사항을 갖고있는 것으로 보입니다. –

+0

"필수"필드를 사용하여이 작업을 수행하려고합니다. 많은 "읽기 전용"작업 환경에서는 시스템이 읽기 전용 값을 저장 /보고하지 않기 때문에 읽기 전용 값이 선택 사항이라고 가정합니다. 광산이 필요하기 때문에 (학생 ID) 양식 확인시 오류가 발생합니다."이 입력란은 필수 입력란입니다." 이것은 사용자 정의 clean_field() 루틴이 호출되기 전에 발생하는 것으로 보입니다. 나는 이것을 다른 질문으로 올릴지도 모른다. – jamida