Объект TypeError не повторяется
Я получаю следующую ошибку при попытке перебрать переменную в моих шаблонах Django. Рассматриваемая переменная является связанным объектом модели, указанной в моем подклассе DetailView:
Ошибка типа в /en/ заявителей /50771459778/
Объект "Домохозяйка" не повторяется
Вот мой models.py
файл:
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)
Вот мой urls.py
файл:
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'),
Вот соответствующая часть моего шаблона, 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>
Часть, которая закомментирована (то есть часть между <!-- -->
тэги), что заставляет меня думать, что я должен быть в состоянии перебрать householdmember
переменная. Но когда я пытаюсь сделать это, это не работает - я просто получаю TypeError выше.
Я много раз искал stackru.com, чтобы найти ответ, но самый близкий ответ, который я смог найти, это: django, как перебрать объект контекста, возвращенный общим подробным представлением?, но это не решает мою проблему, я думаю, потому что я использую представления на основе классов.
Буду очень признателен за любую помощь. Спасибо!
2 ответа
Вы не можете пересмотреть модель. Я рекомендую вам использовать ваш закомментированный код.
Если вы все еще хотите использовать forloop, возможно, вы можете добавить этот код:
class Householdmember(models.Model):
# all yuur fields...
def __iter__(self):
return return [field.value_to_string(self) for field in Householdmember._meta.fields]
Но никто не рекомендует
Так-то лучше:
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 ]
Если ваш файл views.py похож на мой:
from django.shortcuts import render
from django.http import HttpResponse
from django.contrib.auth.forms import UserCreationForm
from .models import Home
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.db.models import Count
# Create your views here.
def homepage(request):
context = RequestContext(request)
titles_string = Home.objects.get(id=2)
print (titles_string)
context_dict = {'titles' : (titles_string)}
print(context_dict)
return render_to_response('main/home.html', context_dict, context)
нужное значение можно распечатать, напечатав в файле шаблона:{{title}}
% extends "main/header.html" %}
{% block title %}
{{titles}}
{% endblock %}
{% block content %}
{{titles}}
{% endblock %}
Мне удалось решить это; вот как. Я использовал информацию отсюда: перебирать имена и значения полей экземпляра модели в шаблоне
Вот что я добавил к своему models.py
файл:
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
А вот то, что мой detail.html
файл в конечном итоге выглядит как:
<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>
И это дает желаемый результат.