基于 Django 类的视图加载另一个带有数据的表单
Posted
技术标签:
【中文标题】基于 Django 类的视图加载另一个带有数据的表单【英文标题】:Django Class based view loading another form with data 【发布时间】:2021-01-25 23:54:38 【问题描述】:我不确定我是否正确使用了这个基于类的视图。我想做的事情我认为很简单。基本上是一个基于模型的表单,我只使用来自以下的“用户”字段:
class OnSiteLog(models.Model):
objects = models.Manager()
user = models.ForeignKey(User, on_delete=models.CASCADE)
checkIn = models.DateTimeField('checkin_date', null=True, blank=True)
checkOut = models.DateTimeField('checkout_date', null=True, blank=True)
notes = models.CharField(null=True, blank=True,max_length = 200)
location = models.CharField(null=True, blank=True, max_length=200)
autoCheckin = models.BooleanField(null=True, blank=True, default=False)
class QueryUser(LoginRequiredMixin, FormView):
model = OnSiteLog
form_class = QueryForm
template_name = 'log/query.html'
success_url = '/'
def post(self, request, *args, **kwargs):
theRecord = OnSiteLog.objects.filter(user_id=24)
print(theRecord[0].user)
super(QueryUser, self).post(request, *args, **kwargs)
return render(request, 'log/query.html', 'log':theRecord)
从那里开始:模板非常简单,形式清晰:
% block content %
<div class="breadcrumb-area">
<!-- Background Curve -->
<div class="breadcrumb-bg-curve">
<img src="% static '/img/core-img/curve-5.png' %" >
</div>
</div>
<div class="container">
<h2> Query for User </h2>
<div class="row">
<div class="col-sm">
% crispy form %
</div>
</div>
<div class="row">
Logs
<div class="col-sm">
<table class="table">
<tr>
<th>User</th>
<th>Check In</th>
<th>Check Out</th>
<th>Location</th>
<th>Notes</th>
</tr>
% for ins in log %
<tr>
<td> ins.user </td>
<td> ins.checkIn </td>
<td> ins.checkOut </td>
<td> ins.location </td>
<td> ins.notes </td>
% if request.user.is_superuser %
<td> <a href="% url 'log_detail' ins.id %"><button type="button" class="btn btn-primary">Edit Entry</button></td>
% endif %
<!-- td><a href=" ins.id "><button type="button" class="btn btn-primary">Edit Insurance</button></a></td>
<td><button type="button" class="btn btn-danger">Delete Insurance</button></td> -->
</tr>
% endfor %
</table>
</div>
</div>
</div>
% endblock %
我想要的是,在他们使用选定的名称提交后重新加载表单,并且重新加载的表单具有来自该用户的 OnSiteLog 的所有登录信息(基本上选择所有用户 = '...' )
虽然我不确定如何从 def post
方法中的请求中获取正确的变量,但我在那里找到了一个好方法,然后作为测试,我输入了 id 24。所以我不确定如何获得它变量输出?
其次,脆皮表格(我认为)一直给我这个错误:
VariableDoesNotExist at /query_user/
Failed lookup for key [form] in ['True': True, 'False': False, 'None': None, , , 'log': <QuerySet [<OnSiteLog: OnSiteLog object (100)>, <OnSiteLog: OnSiteLog object (101)>, <OnSiteLog: OnSiteLog object (107)>, <OnSiteLog: OnSiteLog object (109)>, <OnSiteLog: OnSiteLog object (124)>, <OnSiteLog: OnSiteLog object (148)>, <OnSiteLog: OnSiteLog object (152)>, <OnSiteLog: OnSiteLog object (156)>, <OnSiteLog: OnSiteLog object (158)>, <OnSiteLog: OnSiteLog object (163)>, <OnSiteLog: OnSiteLog object (168)>, <OnSiteLog: OnSiteLog object (172)>, <OnSiteLog: OnSiteLog object (178)>, <OnSiteLog: OnSiteLog object (192)>, <OnSiteLog: OnSiteLog object (193)>, <OnSiteLog: OnSiteLog object (550)>, <OnSiteLog: OnSiteLog object (552)>, <OnSiteLog: OnSiteLog object (556)>, <OnSiteLog: OnSiteLog object (559)>, <OnSiteLog: OnSiteLog object (562)>, '...(remaining elements truncated)...']>]
因此,除了不太确定如何在 def post
中获取正确的变量之外,我也不确定为什么表单的重新呈现会吓坏。
【问题讨论】:
【参考方案1】:您可以尝试覆盖 FormView 的这些方法,并使用适当的上下文再次将用户带到视图以填充表单。
# get the id of the log that was just created
def form_valid(self, form, *args, **kwargs):
user = form.cleaned_data.get('user')
self.log_id = User.objects.get(username=user).select_related('log').last().id
return super().form_valid(form, *args, **kwargs)
# redirect successful form to same view
def get_success_url(self):
return reverse('this-view', kwargs='id': self.log_id)
# render populated form in context
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
try:
context['form'] = self.form_class(instance=OnSiteLog.objects.get(id=self.kwargs['id']))
except ObjectDoesNotExist:
context['form'] = self.form_class()
finally:
return context
然后您应该能够使用您刚刚创建的 OnSiteLog 实例填充您的表单。但是,有了这个,您必须在 url Django optional url parameters 中有可选的 url 参数。
【讨论】:
我将在使用计算机时尝试此操作,尽管 query.html 文件有一个 crispy_form 只是 'user' ,因此没有其他表单可以作为想法填充是我试图通过模板中的 for 循环处理的用户的所有日志的列表。我认为这可能是一个问题,也许类视图期望所有数据都是一种形式? (在这种情况下,我的表单有一个字段)并且不允许“堆叠”或将任何额外数据添加回模板? 我实际上是通过转到第二个 html 文件来准备的硬编码 ID id 是金色的 是的,这听起来不错 - 只是另一个列出用户日志的 ListView。从您的表单中,重定向到该新视图,但在 url 中添加新用户的 id 或用户名:def get_success_url(self): return reverse('new-view', kwargs='id': user.id)
。然后您可以在下一个context
或get_context_data
中使用kwargs['id']
,具体取决于这是CBV 还是FBV。 logs = OnSiteLog.objects.filter(user__id=kwargs['id'])
天哪,我糟透了 :D 我以一种 hacky 的方式做到了。我不敢相信这一点给我带来了麻烦,我显然从来没有过多地混合 CBV 或 FBV。使用教程和什么不是很好,但并不总是显示关于这些东西的具体细节......我编辑了我原来的问题,但仍然不确定如何获得返回的用户 ID,但按照你所说的,我不知道完全在 CBV 中使用 def 帖子....
实际上在这里给出了一个很好的答案,即使我的 hack(是的,total hack)朝着不同的方向发展。这只是一个用于办公室的小型 covid 跟踪应用程序,因此它不是一些强大的企业级应用程序,但您的提示确实有所帮助。我在我的编辑中得到了它的代码,但是对于 .filter(user_id=request.POST.get('user')) 工作得很好(分页不能这样工作,但其余工作正常)。稍后我可能会回来完善它。以上是关于基于 Django 类的视图加载另一个带有数据的表单的主要内容,如果未能解决你的问题,请参考以下文章
带有来自模型的自定义验证消息的 Django 1.5 基于类的视图