kd4*_*ttc 6 django bug-reporting modelform django-generic-views
令人印象深刻的是,功能性网站与教程中的通用视图一起快速发展.此外,表单处理的工作流程很好.我使用ModelForm帮助器类从我制作的模型创建一个表单,并很高兴看到这么多的功能汇集在一起.当我使用通用list_detail.object_detail时,我很失望,我可以显示的所有内容都是单独的字段.我知道ModelForm类包含用于呈现的信息,因此我想将ModelForm与通用视图一起使用.
我正在询问stackoverflow以获得一些方向,并欣赏几张海报的答案和评论.我已经想出如何让它工作,但DetailView中有一个错误.该解决方案包括一种解决方法.
要将ModelView与通用视图一起使用,并使所有字段自动呈现以下工作:
创建一个项目,并在其中创建应用程序住院患者.
如果你有
# inpatients/models.py
class Inpatient(models.Model):
last_name = models.CharField(max_length=30)
first_name = models.CharField(max_length=30,blank=True)
address = models.CharField(max_length=50,blank=True)
city = models.CharField(max_length=60,blank=True)
state = models.CharField(max_length=30,blank=True)
DOB = models.DateField(blank=True,null=True)
notes = models.TextField(blank=True)
def __unicode__(self):
return u'%s, %s %s' % (self.last_name, self.first_name, self.DOB)
class InpatientForm(ModelForm):
class Meta:
model = Inpatient
Run Code Online (Sandbox Code Playgroud)
和
# inpatients/views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response
from django.views.generic import DetailView
from portal.inpatients.models import *
def formtest(request):
if request.method == 'POST':
form = InpatientForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/inpatients')
else:
form = InpatientForm()
return render_to_response("formtest.html", {'form': form})
class FormDetailView(DetailView):
model=Inpatient
context_object_name='inpatient' # defines the name in the template
template_name_field='inpatient_list_page.html'
def get_object(self):
inpatient=super(FormDetailView,self).get_object()
form=InpatientForm(instance=inpatient)
return form
def get_template_names(self):
return ['inpatient_list_page.html',]
Run Code Online (Sandbox Code Playgroud)
和
#urls.py
from django.conf.urls.defaults import patterns, include, url
from django.views.generic import ListView
from portal.inpatients.models import Inpatient, InpatientForm
from portal.inpatients.views import FormDetailView
urlpatterns = patterns('',
(r'^formtest/$','portal.inpatients.views.formtest'),
(r'^inpatients/$', ListView.as_view(
model=Inpatient, template_name='inpatient_list_page.html')),
(r'^inpatient-detail/(?P<pk>\d+)/$', FormDetailView.as_view()),
)
# with a template containing
{% block content %}
<h2>Inpatients</h2>
<ul>
{% for aninpatient in object_list %}
<li><a href='/inpatient-detail/{{ aninpatient.id }}/'>
{{ aninpatient }}, id={{ aninpatient.id }}</a></li>
{% endfor %}
</ul>
{{ inpatient.as_p }}
{% endblock %}
# Yeah, kind of hokey. The template is for both the list view and detail view.
# Note how the form is rendered with one line - {{ inpatient.as_p }}
Run Code Online (Sandbox Code Playgroud)
有用.使用基于类的通用视图的 说明位于https://docs.djangoproject.com/en/1.3/topics/class-based-views/.说明非常明确.使事情有效的关键是重新定义get_object.在"执行额外工作"部分的文档中,它很好地描述了如何执行此操作,步骤是调用get_object的原始版本,然后是额外的工作.我意识到的一点是返回对象可以是ModelForm对象.get_object返回的对象直接进入渲染中的模板.通过获取检索到的住院病人对象并通过InpatientForm运行它,它可以作为一个表单传递给视图,然后呈现自己.
至于错误:DetailView中的错误是get_template_names函数尝试从不存在的结构中创建模板名称.在 第127到140行的https://code.djangoproject.com/browser/django/trunk/django/views/generic/detail.py中,我们在SingleObjectTemplateResponseMixin.get_template_names中:
127 # The least-specific option is the default <app>/<model>_detail.html;
128 # only use this if the object in question is a model.
129 if hasattr(self.object, '_meta'):
130 names.append("%s/%s%s.html" % (
131 self.object._meta.app_label,
132 self.object._meta.object_name.lower(),
133 self.template_name_suffix
134 ))
135 elif hasattr(self, 'model') and hasattr(self.model, '_meta'):
136 names.append("%s/%s%s.html" % (
137 self.model._meta.app_label,
138 self.model._meta.object_name.lower(),
139 self.template_name_suffix
140 ))
Run Code Online (Sandbox Code Playgroud)
错误是第131行上的代码被执行并且出现错误消息<'ModelFormOptions'对象没有属性'app_label'>.我得出结论,定义了_meta对象.我想问题是在ModelForm中定义了Meta类.该Meta可能没有设置预期的字段.解决方法是重写get_template_names并返回正确的模板.
我是Django和Python的新手.我很感谢贡献者在我之前提出的以下问题中给出的答案和评论.( 把链接在list_detail.object_list到list_detail.object_detail, 在使用object_detail并形式, 在Django滚动你自己的通用视图)
我该怎么做才能报告错误?
我相信你是对的。这是一个错误,源于 ModelForm 和 Models 都有 _meta 属性。get_object()
每当从包含 _meta 属性的对象返回时,都会出现同样的错误。
get_object
不必返回 Model 实例。您可以通过查看源代码DetailView
并阅读其文档字符串来确认这一点:
class DetailView(SingleObjectTemplateResponseMixin, BaseDetailView):
"""
Render a "detail" view of an object.
By default this is a model instance looked up from `self.queryset`, but the
view will support display of *any* object by overriding `self.get_object()`.
"""
Run Code Online (Sandbox Code Playgroud)
请注意,文档字符串明确表示重写 self.get_object() 支持任何对象。
另一条确凿的证据来自该错误本身发生的位置,即get_template_names method
的SingleObjectTemplateResponseMixin
。
# The least-specific option is the default <app>/<model>_detail.html;
# only use this if the object in question is a model.
if hasattr(self.object, '_meta'):
names.append("%s/%s%s.html" % (
self.object._meta.app_label,
self.object._meta.object_name.lower(),
self.template_name_suffix
))
elif hasattr(self, 'model') and hasattr(self.model, '_meta'):
names.append("%s/%s%s.html" % (
self.model._meta.app_label,
self.model._meta.object_name.lower(),
self.template_name_suffix
))
Run Code Online (Sandbox Code Playgroud)
再次查看这段代码,注释本身说“如果有问题的对象是模型”。从这个评论我们可以推断该对象并不总是必须是模型。
但是,如果您尝试创建一个允许某人编辑/创建/删除模型的视图,您确实应该看看编辑视图,其中包括 FormView、CreateView、EditView 和 DeleteView。您可以在https://docs.djangoproject.com/en/1.3/ref/class-based-views/#editing-views中查看更多信息。
要回答有关如何报告错误的问题,您应该遵循https://docs.djangoproject.com/en/1.3/internals/contributing/#reporting-bugs中详细说明的指南。
归档时间: |
|
查看次数: |
6784 次 |
最近记录: |