BRH*_*HSM 9 html python forms django
我已经制作了一个django表单,我想在其中传递一些我需要显示的上下文(主要是标签中的数据库条目,以便用户可以从中进行选择).因此我在get_context_data function这里添加上下文到现有的上下文,如下所示:
def get_context_data(self, **kwargs):
context = super(UploadView, self).get_context_data(**kwargs)
context['categories'] = Category.objects.all()
context['form'] = VideoForm
return context
Run Code Online (Sandbox Code Playgroud)
但是,表单不保存传递给数据库的信息.为什么那不起作用?
这是我的代码的一部分!
forms.py:
class VideoForm(forms.ModelForm):
category = forms.ModelChoiceField(queryset=Category.objects.all(), empty_label=None)
class Meta:
model = Video
fields = [
'title',
'description',
'description_short',
'category',
'time',
'thumbnail',
'type',
]
def clean_thumbnail(self):
picture = self.cleaned_data.get("thumbnail")
if not picture:
raise forms.ValidationError("No Image")
else:
w, h = get_image_dimensions(picture)
if w/h != (16/9):
raise forms.ValidationError("Image in wrong aspect ratio (should be 16:9)")
return picture
Run Code Online (Sandbox Code Playgroud)
upload.html(它很长,所以最好将它上传到Pastebin)
views.py:
class UploadView(LoginRequiredMixin, CreateView):
form_class = VideoForm
template_name= 'upload.html'
def form_valid(self, form):
instance = form.save(commit=False)
instance.uploader=self.request.user
return super(UploadView, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(UploadView, self).get_context_data(**kwargs)
context['categories'] = Category.objects.all()
context['form'] = VideoForm
return context
Run Code Online (Sandbox Code Playgroud)
我正在使用自定义表单,所以我可以设置用于编辑CSS的类(而不是仅使用form.as_p并且从那里开始非常难看......)
编辑:
经过一些测试后,我发现如果我放入函数print(instance)内部def form_valid(self, form):就不会打印出任何内容,建议实例为空.怎么会这样?此外,我尝试删除:context['form'] = VideoForm并没有出现错误,但如果我正确填写表格,它仍然无法正常工作!
编辑2:
我创建了一个'form_invalid'函数,如下所示:
def form_invalid(self, form):
print(form.instance)
return super(UploadView, self).form_invalid()
Run Code Online (Sandbox Code Playgroud)
什么导致:
TypeError: form_invalid() missing 1 required positional argument: 'form'
Run Code Online (Sandbox Code Playgroud)
这让我想到,当我在提交后重定向回到表单时,我没有收到任何错误.这是我写的表格:https://pastebin.com/3H6VRZR1
我也尝试用它来测试它form.as_p导致同样的问题
编辑3:
在测试了一些答案之后,我们发现HTML页面本身的形式可能是因为表单form_invalid()完全是空的.我决定再试form.as_p一次,看看它是否仍然导致与我的自定义表单相同的问题.现在我收到一个新错误:
null value in column "category_id" violates not-null constraint
DETAIL: Failing row contains (8, test new fom reg, test-new-fom-reg, null, test, test, 2018-01-10 13:44:58.81876+00, 2018-01-10 13:44:58.818789+00, 1, thumbnails/test-new-fom-reg.png, 2, 1, /home/trie/Desktop/django/vidmiotest/media/videos/test.mp4).
Run Code Online (Sandbox Code Playgroud)
有:
USER
admin
GET
No GET data
POST
Variable Value
title 'test new fom reg'
category '8'
type '1'
time '1'
description 'test'
csrfmiddlewaretoken `BeizxWHU5KDbixit9vpxKoxEeBxgU9MNITaNlkM1qtI0Aq6kIThHrtjfUsQXjxON'
description_short 'test'
FILES
Variable Value
thumbnail <TemporaryUploadedFile: sixteentonineratio.png (image/jpeg)>
videoFile <TemporaryUploadedFile: test 3.mp4 (video/mp4)>
Run Code Online (Sandbox Code Playgroud)
作为数据从表格中发送的数据,表明(基于此)category_id不在我的表格模型中.它是什么(该领域刚刚被称为category),但它为什么认为它应该在那里?
我刚刚检查了phppgadmin以查看数据库的样子,并且id_category在我的模型中调用了字段,它被称为类别,为什么?
编辑4:我从未在上面的错误中添加Traceback:
内部服务器错误:/ upload/Traceback(最近一次调用最后一次):文件"/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/backends/utils.py",行85,在_execute中返回self.cursor.execute(sql,params)psycopg2.IntegrityError:列"category_id"中的空值违反非空约束DETAIL:失败行包含(12,test,test,null,test,test,2018 -01-16 18:18:25.907513 + 00,2018-01-16 18:18:25.907538 + 00,6,缩略图/ test_d1MHjMX.png,2,1,/ home/trie/Desktop/django/vidmiotest/media /视频/ test.mp4).
上述异常是以下异常的直接原因:
Traceback (most recent call last):
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/views/generic/base.py", line 69, in view
return self.dispatch(request, *args, **kwargs)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/contrib/auth/mixins.py", line 52, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/views/generic/base.py", line 89, in dispatch
return handler(request, *args, **kwargs)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/views/generic/edit.py", line 172, in post
return super().post(request, *args, **kwargs)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/views/generic/edit.py", line 142, in post
return self.form_valid(form)
File "/home/trie/Desktop/django/vidmiotest/upload/views.py", line 21, in form_valid
instance.save()
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/models/base.py", line 729, in save
force_update=force_update, update_fields=update_fields)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/models/base.py", line 759, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/models/base.py", line 842, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/models/base.py", line 880, in _do_insert
using=using, raw=raw)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/models/query.py", line 1125, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 1280, in execute_sql
cursor.execute(sql, params)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/backends/utils.py", line 100, in execute
return super().execute(sql, params)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/backends/utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/trie/Desktop/django/venv/lib/python3.5/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: null value in column "category_id" violates not-null constraint
DETAIL: Failing row contains (12, test, test, null, test, test, 2018-01-16 18:18:25.907513+00, 2018-01-16 18:18:25.907538+00, 6, thumbnails/test_d1MHjMX.png, 2, 1, /home/trie/Desktop/django/vidmiotest/media/videos/test.mp4).
Run Code Online (Sandbox Code Playgroud)
问题的问题是调用super().form_valid()并用context ['form'] = VideoForm覆盖构造的表单.让框架在使用CreateView时设置表单.
继承的CreateView提供了设置表单,保存表单,在视图上设置self.object以及重定向到成功URL的功能.
即CreateView.form_valid提供:
self.object = form.save()
Run Code Online (Sandbox Code Playgroud)
解决方案在UploadView中设置上传器是正确的,但调用super.form_valid将尝试再次保存表单.
据我所知,期望的行为是:
在代码中:
instance = form.save(commit=False)
instance.uploader = self.request.user
instance.save()
return redirect(self.get_success_url()) # Skip the call to super
Run Code Online (Sandbox Code Playgroud)
另外在其他答案中指出,context ['form'] = VideoForm将覆盖CreateView的表单设置.
我建议看看执行流程如何为CreateView工作,它将在GET和POST情况下为模板上下文设置表单.
另一种解决方法是允许VideoForm在init中接受上传器:
class VideoForm(forms.ModelForm):
def __init__(self, uploader, *args, **kwargs):
self.uploader = uploader
super().__init__(*args, **kwargs)
def save(self, commit=True):
instance = super().save(commit=False)
instance.uploader = self.uploader
if commit:
instance.save()
return instance
Run Code Online (Sandbox Code Playgroud)
并提供表格的上传者
class UploadView(..., CreateView):
def get_form_kwargs(self):
kwargs= super().get_form_kwargs()
kwargs['uploader'] = self.request.user
return kwargs
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你.
看编辑3:
之所以说'category_id'是因为django模型中的外键会自动以'_id'为后缀作为数据库中的列名.文档.
视频模型可能具有类别的外键.
如果在数据库中找到id_category,则可能与迁移/模型不同步?您应该尝试清除数据库和/或重新运行makemigrations/migrate