在基于 Django class 的通用视图 CreateView 中设置表单字段
Setting form fields in django class based generic view CreateView
我正在使用 django 的 CreateView
将图像添加到书中。我将图书的 ID 作为 url 中的参数传递给基于 class 的视图。 book
和 language
等表单字段不会在模板上呈现,而是借助图书 ID 获得的。
# views.py
class PictureCreateView(CreateView):
model = Upload
fields = "__all__"
book_id = None
def get_initial(self):
initial = super(PictureCreateView, self).get_initial()
initial = initial.copy()
self.book_id = self.kwargs['book_id']
book = Book.objects.get(id=self.book_id)
initial['book'] = book
initial['language'] = language
initial['uploader'] = self.request.user
return initial
# set book_id so it used in the template
def get_context_data(self, **kwargs):
context = super(PictureCreateView, self).get_context_data(**kwargs)
context['book_id'] = self.book_id
return context
def form_valid(self, form, **kwargs):
print('Form is valid')
self.object = form.save()
files = [serialize(self.object)]
data = {'files': files}
response = JSONResponse(data, mimetype=response_mimetype(self.request))
response['Content-Disposition'] = 'inline; filename=files.json'
return super(PictureCreateView, self).form_valid(form)
def form_invalid(self, form):
print('Form invalid!')
print(form.errors)
data = json.dumps(form.errors)
return HttpResponse(content=data, status=400, content_type='application/json')
# models.py
class Upload(models.Model):
image = models.ImageField(upload_to=get_upload_path, help_text='Image to process')
uploader = models.ForeignKey(settings.AUTH_USER_MODEL, models.CASCADE, related_name='uploader')
language = models.ForeignKey(Language, models.CASCADE)
book = models.ForeignKey(Book, models.CASCADE)
问题是我收到一条错误消息,指出表单无效,并且字段 uploader
、book
和 language
是必需的。我该如何解决?
initial
数据用于在最初显示表单时显示默认值。当提交的表单数据中缺少这些值时,不会使用它。如果像 book
和 uploader
这样的字段是从 URL 或 logged-in 用户设置的,那么你应该将它们完全留在表单之外,而不是在初始数据中设置它们.然后,您可以在保存表单之前在 form_valid
方法中设置实例的值。
from django.contrib.auth.mixins import LoginRequiredMixin
class PictureCreateView(LoginRequiredMixin, CreateView):
model = Upload
fields = ['other_field1', 'other_field2', ...] # leave out book, language and uploader
def form_valid(self, form):
self.book_id = self.kwargs['book_id']
book = Book.objects.get(id=self.book_id)
form.instance.book = book
form.instance.language = ????
form.instance.uploader = self.request.user
return super(
LoginRequiredMixin
确保只有 logged-in 用户可以访问该视图。
您可能希望使用 get_object_or_404
来处理 book_id
引用不存在的书籍的情况。
一想,初始不填模型提交。您需要在 init
中执行此操作
def __init__(self):
super(PictureCreateView, self).__init__()
self.fields['book'] = self.initial['book']
self.fields['uploader'] = self.initial['uploader']
self.fields['language'] = self.initial['book']
或者,如果您不想设置字段,请确保它们在您的原始模型中是可选的:
class Upload(models.Model):
uploader = models.ForeignKey('uploader', on_delete=models.CASCADE, null=True, blank=True)
book = models.ForeignKey('book', on_delete=models.CASCADE, null=True, blank=True)
language = models.ForeignKey('language', on_delete=models.CASCADE, null=True, blank=True)
我正在使用 django 的 CreateView
将图像添加到书中。我将图书的 ID 作为 url 中的参数传递给基于 class 的视图。 book
和 language
等表单字段不会在模板上呈现,而是借助图书 ID 获得的。
# views.py
class PictureCreateView(CreateView):
model = Upload
fields = "__all__"
book_id = None
def get_initial(self):
initial = super(PictureCreateView, self).get_initial()
initial = initial.copy()
self.book_id = self.kwargs['book_id']
book = Book.objects.get(id=self.book_id)
initial['book'] = book
initial['language'] = language
initial['uploader'] = self.request.user
return initial
# set book_id so it used in the template
def get_context_data(self, **kwargs):
context = super(PictureCreateView, self).get_context_data(**kwargs)
context['book_id'] = self.book_id
return context
def form_valid(self, form, **kwargs):
print('Form is valid')
self.object = form.save()
files = [serialize(self.object)]
data = {'files': files}
response = JSONResponse(data, mimetype=response_mimetype(self.request))
response['Content-Disposition'] = 'inline; filename=files.json'
return super(PictureCreateView, self).form_valid(form)
def form_invalid(self, form):
print('Form invalid!')
print(form.errors)
data = json.dumps(form.errors)
return HttpResponse(content=data, status=400, content_type='application/json')
# models.py
class Upload(models.Model):
image = models.ImageField(upload_to=get_upload_path, help_text='Image to process')
uploader = models.ForeignKey(settings.AUTH_USER_MODEL, models.CASCADE, related_name='uploader')
language = models.ForeignKey(Language, models.CASCADE)
book = models.ForeignKey(Book, models.CASCADE)
问题是我收到一条错误消息,指出表单无效,并且字段 uploader
、book
和 language
是必需的。我该如何解决?
initial
数据用于在最初显示表单时显示默认值。当提交的表单数据中缺少这些值时,不会使用它。如果像 book
和 uploader
这样的字段是从 URL 或 logged-in 用户设置的,那么你应该将它们完全留在表单之外,而不是在初始数据中设置它们.然后,您可以在保存表单之前在 form_valid
方法中设置实例的值。
from django.contrib.auth.mixins import LoginRequiredMixin
class PictureCreateView(LoginRequiredMixin, CreateView):
model = Upload
fields = ['other_field1', 'other_field2', ...] # leave out book, language and uploader
def form_valid(self, form):
self.book_id = self.kwargs['book_id']
book = Book.objects.get(id=self.book_id)
form.instance.book = book
form.instance.language = ????
form.instance.uploader = self.request.user
return super(
LoginRequiredMixin
确保只有 logged-in 用户可以访问该视图。
您可能希望使用 get_object_or_404
来处理 book_id
引用不存在的书籍的情况。
一想,初始不填模型提交。您需要在 init
中执行此操作def __init__(self):
super(PictureCreateView, self).__init__()
self.fields['book'] = self.initial['book']
self.fields['uploader'] = self.initial['uploader']
self.fields['language'] = self.initial['book']
或者,如果您不想设置字段,请确保它们在您的原始模型中是可选的:
class Upload(models.Model):
uploader = models.ForeignKey('uploader', on_delete=models.CASCADE, null=True, blank=True)
book = models.ForeignKey('book', on_delete=models.CASCADE, null=True, blank=True)
language = models.ForeignKey('language', on_delete=models.CASCADE, null=True, blank=True)