2013-08-29 41 views
6

Tôi nhận được lỗi sau khi cố gắng lặp qua một biến trong các mẫu Django của tôi. Các biến trong câu hỏi là các đối tượng có liên quan của mô hình quy định tại lớp con DetailView tôi:Loại đối tượng lỗi không thể lặp lại

TypeError tại/en/ứng/50771459778/

đối tượng 'Householdmember' không phải là iterable

đây là models.py tập tin của tôi:

class Applicant(models.Model): 
    user    = models.ForeignKey(User, editable=False) 
    bank_card_number = models.CharField(_('Bank card number'),max_length=50, unique=True) 
    site_of_interview = models.IntegerField(_('Site of interview'), choices = SITE_CHOICES, default=TIRANA, blank=False) 
    housenumber  = models.CharField(_('House Number'),max_length=8) 
    address_line1  = models.CharField(_('Address line 1'),max_length=50) 
    address_line2  = models.CharField(_('Apt #'),max_length=50,blank=True) 
    municipality  = models.CharField(_('Municipality/commune'),max_length=25) 
    district   = models.CharField(_('District'),max_length=25,blank=True) 
    urban    = models.IntegerField(_('Area (urban/rural)'), choices = AREA_CHOICES, blank=False) 
    postal   = models.CharField(_('Postal code'),max_length=25,blank=True) 

class Householdmember(models.Model): 
    applicant   = models.ForeignKey(Applicant) 
    first_name  = models.CharField(_('First name'),max_length=50,blank=False) 
    middle_name  = models.CharField(_('Middle name'),max_length=50,blank=True) 
    last_name   = models.CharField(_('Last name'),max_length=50,blank=False) 
    national_id  = models.CharField(_('National ID'),max_length=50,blank=False, unique=True) 
    male    = models.IntegerField(_('Gender'), choices = GENDER_CHOICES, blank=False) 
    date_of_birth  = models.DateField() 
    rel_to_head  = models.IntegerField(_('Gender'), choices = RELTOHEAD_CHOICES, blank=False) 
    disability  = models.IntegerField(_('Is disabled?'), choices = YESNO_CHOICES, blank=False) 
    created_at  = models.DateTimeField(auto_now_add = True) 
    updated_at  = models.DateTimeField(auto_now = True) 

đây là tập tin urls.py tôi:

class ListViewApplicants(ListView): 
    paginate_by = 100 
    def get_queryset(self): 
     return Applicant.objects.all() 

class DetailViewUnmask(DetailView): 
    def get_object(self): 
     return self.get_queryset().get(pk=mask_toggle(self.kwargs.get("pk_masked"))) 

urlpatterns = patterns('', 
    url(r'^$', 
     login_required(ListViewApplicants.as_view( 
          template_name='applicants/index.html', 
          #context_object_name='form', 
          )), 
     name='index'), 
    url(r'^(?P<pk_masked>\d+)/$', 
     login_required(DetailViewUnmask.as_view(model=Applicant, 
          template_name='applicants/detail.html' 
          )), 
     name='detail'), 

Dưới đây là phần có liên quan của mẫu của tôi, detail.html:

<h2>Household members</h2> 
<table class="package_detail"> 
    <tr> 
     {% include "applicants/householdmember_heading_snippet.html" %} 
    </tr> 

    {% for householdmember in applicant.householdmember_set.all %} 
    <tr> 

     {% for field in householdmember %} 
      <td>{{ field }}</td> 
     {% endfor %} 
     <!-- 
     <td>{{ householdmember.first_name }}</td> 
     <td>{{ householdmember.middle_name }}</td> 
     <td>{{ householdmember.last_name }}</td> 
     <td>{{ householdmember.national_id }}</td> 
     <td>{{ householdmember.get_male_display }}</td> 
     <td>{{ householdmember.date_of_birth }}</td> 
     <td>{{ householdmember.get_rel_to_head_display }}</td> 
     <td>{{ householdmember.get_disability_display }}</td> 
     --> 
    </tr> 
    {% endfor %} 
</table> 

Phần mà là nhận xét ra (ví dụ: phần giữa các thẻ <!-- -->) hoạt động, khiến tôi nghĩ rằng tôi có thể lặp lại biến số householdmember. Nhưng khi tôi cố gắng làm như vậy, nó không hoạt động - tôi chỉ nhận được TypeError ở trên.

Tôi đã tìm kiếm stackoverflow.com exentsively cho một câu trả lời, nhưng câu trả lời gần nhất tôi có thể tìm thấy là: django how to loop through the context object passed back by a generic detailview?, nhưng nó không giải quyết được vấn đề của tôi, tôi nghĩ bởi vì tôi đang sử dụng lớp học dựa trên quan điểm.

Rất cảm kích mọi trợ giúp. Cảm ơn!

Trả lời

3

Bạn không thể lặp qua phiên bản mẫu. Tôi khuyên bạn nên sử dụng mã nhận xét của mình.

Nếu bạn vẫn muốn sử dụng một forloop, có lẽ bạn có thể thêm mã này:

class Householdmember(models.Model): 
    # all yuur fields... 

    def __iter__(self): 
     return return [field.value_to_string(self) for field in Householdmember._meta.fields] 

Nhưng, không ai khuyên

Đó là tốt hơn:

class Householdmember(models.Model): 
    # all yuur fields... 

    def __iter__(self): 
     return [ self.first_name, 
       self.middle_name, 
       self.last_name, 
       self.national_id, 
       self.get_male_display, 
       self.date_of_birth, 
       self.get_rel_to_head_display, 
       self.get_disability_display ] 
+0

Xin chào Lalo, cảm ơn bạn đã phản hồi nhanh chóng. Một câu hỏi: 'Project' trong' for field trong Project._meta.fields' trong mã của bạn ở trên là gì? –

+0

Xin lỗi, đó phải là Hộ gia đình – lalo

0

tôi quản lý để giải quyết điều này; đây là cách. Tôi đã sử dụng thông tin từ đây: Iterate over model instance field names and values in template

Dưới đây là những gì tôi thêm vào models.py tập tin của tôi:

def get_all_fields(self): 
    fields = [] 
    for f in self._meta.fields: 
     fname = f.name   
     # resolve picklists/choices, with get_xyz_display() function 
     get_choice = 'get_'+fname+'_display' 
     if hasattr(self, get_choice): 
      value = getattr(self, get_choice)() 
     else: 
      try : 
       value = getattr(self, fname) 
      except User.DoesNotExist: 
       value = None 

     # only display fields with values and skip some fields entirely 
     if f.editable and f.name not in ('id', 'created_at', 'updated_at', 'applicant'): 

      fields.append(
       { 
       'label':f.verbose_name, 
       'name':f.name, 
       'value':value, 
       } 
      ) 
    return fields 

Và đây là những gì tập tin detail.html của tôi đã kết thúc tìm kiếm như:

<table class="package_detail"> 
    <tr> 
     {% include "applicants/householdmember_heading_snippet.html" %} 
    </tr> 
    {% for householdmember in applicant.householdmember_set.all %} 
    <tr>  
    {% for field in householdmember.get_all_fields %} 
     <td>{{ field.value }}</td> 
    {% endfor %} 
    </tr> 
    {% endfor %} 
</table> 

Và điều này mang lại đầu ra mong muốn.

Các vấn đề liên quan