2010-05-31 5 views
0

교사가 학생의 이름을 변경하지 않아도되는 성적을 업데이트 할 수있는 간단한 "성적 책"응용 프로그램을 구현하고 있습니다 (적어도 업데이트가 아닌 경우). 학년 페이지). 이렇게하려면 가장 간단한 방법 인 읽기 전용 트릭 중 하나를 사용하고 있습니다. 문제는 SUBMIT 이후 학생들에게 '빈'값으로보기가 다시 표시된다는 것입니다. 학생들의 이름이 다시 나타나기를 바랍니다.저장 후 CharField 값이 사라짐 (읽기 전용 필드)

다음은이 문제를 보여주는 가장 간단한 예제입니다. (DB 디자인이 좋지 않다는 것을 알고 있습니다.) 실제 예제에서 학생은 자체 테이블에 있지만 문제가 여전히 존재합니다.)

models.py

class Grade1(models.Model): 
    student = models.CharField(max_length=50, unique=True) 
    finalGrade = models.CharField(max_length=3) 

class Grade1OForm(ModelForm): 
    student = forms.CharField(max_length=50, required=False) 
    def __init__(self, *args, **kwargs): 
     super(Grade1OForm,self).__init__(*args, **kwargs) 
     instance = getattr(self, 'instance', None) 
     if instance and instance.id: 
      self.fields['student'].widget.attrs['readonly'] = True 
      self.fields['student'].widget.attrs['disabled'] = 'disabled' 
    def clean_student(self): 
     instance = getattr(self,'instance',None) 
     if instance: 
      return instance.student 
     else: 
      return self.cleaned_data.get('student',None) 
    class Meta: 
     model=Grade1 

views.py

from django.forms.models import modelformset_factory 
def modifyAllGrades1(request): 
    gradeFormSetFactory = modelformset_factory(Grade1, form=Grade1OForm, extra=0) 
    studentQueryset = Grade1.objects.all() 
    if request.method=='POST': 
     myGradeFormSet = gradeFormSetFactory(request.POST, queryset=studentQueryset) 
     if myGradeFormSet.is_valid(): 
      myGradeFormSet.save() 
      info = "successfully modified" 
    else: 
     myGradeFormSet = gradeFormSetFactory(queryset=studentQueryset) 
    return render_to_response('grades/modifyAllGrades.html',locals()) 

템플릿

<p>{{ info }}</p> 
<form method="POST" action=""> 
<table> 
{{ myGradeFormSet.management_form }} 
{% for myform in myGradeFormSet.forms %} 
    {# myform.as_table #} 
    <tr> 
    {% for field in myform %} 
    <td> {{ field }} {{ field.errors }} </td> 
    {% endfor %} 
    </tr> 
{% endfor %} 
</table> 
<input type="submit" value="Submit"> 
</form> 

답변

1

읽기 전용 필드 표시 방법 입니다.

학생 필드가 비활성화되어 있기 때문에 제출 양식에 입력 된 내용이 없으므로 유효성 검사 오류 메시지와 함께 표시되는 오류 양식에 초기 값이 표시되지 않습니다.

ReadOnly 위젯은 html로 비활성화 된 필드보다 복잡해야합니다.

ReadOnlyWidget (_has_changed)보다 우선하는 것을 사용하십시오.

다음은 내가 사용하는 것입니다. 인스턴스화의 경우 original_value와 선택적으로 display_value (다른 경우)가 필요합니다.

class ReadOnlyWidget(forms.Widget): 

    def __init__(self, original_value, display_value=None): 
     self.original_value = original_value 
     if display_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 
+0

Lakshman에게 감사 드려요.하지만 저는 장고를 여전히 좋아합니다. 원래 값은 어떻게 설정합니까? 나는 그것을 다음처럼 호출하려고한다. student = forms.CharField (max_length = 50, widget = ReadOnlyWidget()) 그러나 원래 값을 전달해야하므로 올바르지 않다. 참고 ... 내 최종 목표는 modelformset에서 이것을 사용하는 것입니다. – jamida

+0

jamida : 학생 인스턴스 인 ReadOnlyWidget에 전달하면 폼에 읽기 전용으로 표시됩니다. –

+0

모델 서식에서 어떻게 수행합니까? 위의 코드 샘플 또는 양식의 __init__ 루틴에서이 작업을 수행합니까? (또는?) 그리고 init 루틴의 경우, init 루틴에서 위젯을 참조하려면 어떻게해야합니까? 나는 문서를 읽는 것에 대해 개방적이지만 장고에 관한이 문서는 잘 설명되어 있지 않다. 링크가 있다면, 좋을 것입니다! – jamida

0

나는 약간의 생각을하기 때문에 여기 약간의 스트레칭을하고 있기 때문에 약간의 생각 :

% 브라우저와 서버간에 전송되는 트래픽을 정확히 파악 했습니까?

% 학생 이름을 숨김 필드로 보내야합니까 (그렇지 않으면 DB 업데이트가 학생 비어 있다고 가정 할 수 있습니다)?

% 파이썬이 파싱 한 후 HTML 소스를 보았습니까?

+0

몇 가지 관련 의견을 보내 주셔서 감사합니다. 하나는 다른 Readonly 트릭이 잘 작동한다는 것입니다. 그러나 Student 필드가 다른 테이블 (내 전체 앱)의 외래 키인 경우 해당 트릭이 작동하지 않습니다. 또 하나는 생성 된 HTML 및 POST 변수를 살펴 보았습니다. Django는 학생을 다시 얻지 않습니다. 이는 DISABLED 및/또는 READONLY 필드에서 정상입니다. CLEAN 루틴이 올바른 값을 설정하기 때문에 문제가되지 않습니다. 마지막으로 clean 루틴의 else 절에 print 문을 넣었습니다. 호출되지 않았습니다. 따라서 학생은 항상 이용 가능합니다. – jamida