关键词:
【中文标题】django - 使用 FormView 和 ModelForm 更新模型【英文标题】:django - update model with FormView and ModelForm 【发布时间】:2014-03-03 14:59:37 【问题描述】:我不知道如何在FormView
中使用ModelForm
来更新已经存在的实例??
此 URL 上的 POST 表单:r'/object/(?P<pk>)/'
我使用ModelForm
(而不是直接使用UpdateView
),因为其中一个字段是必需的,我对其进行了清理。
我基本上想在FormView
(在POST)中初始化表单时提供kwarg instance=...
,以便它绑定到在url中给出pk的对象。但我不知道在哪里做...
class SaveForm(ModelForm):
somedata = forms.CharField(required=False)
class Meta:
model = SomeModel # with attr somedata
fields = ('somedata', 'someotherdata')
def clean_somedata(self):
return sometransformation(self.cleaned_data['somedata'])
class SaveView(FormView):
form_class = SaveForm
def form_valid(self, form):
# form.instance here would be == SomeModel.objects.get(pk=pk_from_kwargs)
form.instance.save()
return ...
【问题讨论】:
我不太明白你为什么不能使用UpdateView
。你能发布你的视图代码吗?
@jproffitt 清楚为什么我现在不能使用 UpadteView 了吗?
似乎答案在SingleObjectMixin
中(或停止尝试使用django 基于类的通用视图)
不清楚。 UpdateView 继承自 SingleObjectMixin。看来这正是您所需要的。如果您在场地上进行清洁并不重要。您不想用现有数据填充表单吗?
对于可能遇到此问题的其他人:如果您发现必须添加 blank=True, null=True
以使事情得到足够的验证以进行后处理,您最好将模型解耦并表单,只使用表单,然后手动创建模型实例。在许多用例中对我来说效果更好,例如当您需要访问 request.user
时。
【参考方案1】:
您可以使用 FormView 的 post 方法获取发布的数据并使用 form.save() 保存到模型。希望这会有所帮助。
试试这个
class SaveForm(ModelForm):
somedata = forms.CharField(required=False)
class Meta:
model = SomeModel # with attr somedata
fields = ('somedata', 'someotherdata')
def __init__(self, *args, **kwargs):
super(SaveForm, self).__init__(*args, **kwargs)
def save(self, id):
print id #this id will be sent from the view
instance = super(SaveForm, self).save(commit=False)
instance.save()
return instance
class SaveView(FormView):
template_name = 'sometemplate.html'
form_class = SaveForm
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
form.save(kwargs.get('pk'))
else:
return self.form_invalid(form)
【讨论】:
不使用 URL 中的“pk”,这对我没有帮助 检查我已经添加了从视图中获取 pk 到表单中的逻辑。希望这会有所帮助。【参考方案2】:在与您讨论后,我仍然不明白您为什么不能使用UpdateView
。如果我理解正确,这似乎是一个非常简单的用例。您有一个要更新的模型。而且您有一个自定义表单可以在将其保存到该模型之前进行清理。似乎UpdateView
可以正常工作。像这样:
class SaveForm(ModelForm):
somedata = forms.CharField(required=False)
class Meta:
model = SomeModel # with attr somedata
fields = ('somedata', 'someotherdata')
def clean_somedata(self):
return sometransformation(self.cleaned_data['somedata'])
class SaveView(UpdateView):
template_name = 'sometemplate.html'
form_class = SaveForm
model = SomeModel
# That should be all you need. If you need to do any more custom stuff
# before saving the form, override the `form_valid` method, like this:
def form_valid(self, form):
self.object = form.save(commit=False)
# Do any custom stuff here
self.object.save()
return render_to_response(self.template_name, self.get_context_data())
当然,如果我误解了你,请告诉我。不过你应该可以让它工作。
【讨论】:
很好,我只是没明白我们可以在UpdateView
中使用 form_class 属性
再想一想,你真的需要self.object = form.save(commit=False)
吗?
不,如果您不打算进行任何其他更改,则不这样做。你可以只做self.object = form.save()
并取出self.object.save()
。更好的是,您可以删除整个 form_valid
方法。我只是把它放在那里,以防您在将对象保存到数据库之前需要对对象进行任何其他处理。
对,但我的意思是:self.object
在调用form_valid
之前不是已经定义了吗?
是的。但是form_valid
是应该从表单中保存对象的位置。如果您查看ModelFormMixin
的form_valid
方法(UpdateView
继承自),它就是这样做的:self.object = form.save()
。所以要么打电话给super().form_valid
,要么自己保存表格。就像我展示的那样。【参考方案3】:
对于此线程的任何其他访问者,是的,您可以创建一个 FormView
,其作用类似于 CreateView
和 UpdateView
。尽管有其他用户的一些意见,但如果您希望有一个 单个 表单/URL/页面用于 Web 表单以保存一些用户数据,这些数据可以是可选的,但需要得救一次且只有一次。您不希望为此有 2 个 URL/视图,而只有一个显示表单的页面/URL,如果用户已保存模型,则填充要更新的先前数据。
考虑一种像这样的“接触”模型:
from django.conf import settings
from django.db import models
class Contact(models.Model):
"""
Contact details for a customer user.
"""
user = models.OneToOneField(settings.AUTH_USER_MODEL)
street = models.CharField(max_length=100, blank=True)
number = models.CharField(max_length=5, blank=True)
postal_code = models.CharField(max_length=7, blank=True)
city = models.CharField(max_length=50, blank=True)
phone = models.CharField(max_length=15)
alternative_email = models.CharField(max_length=254)
所以,你给它写一个ModelForm
,像这样:
from django import forms
from .models import Contact
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
exclude = ('user',) # We'll set the user later.
您的FormView
同时具有“创建”和“更新”功能将如下所示:
from django.core.urlresolvers import reverse
from django.views.generic.edit import FormView
from .forms import ContactForm
from .models import Contact
class ContactView(FormView):
template_name = 'contact.html'
form_class = ContactForm
success_url = reverse('MY_URL_TO_REDIRECT')
def get_form(self, form_class):
"""
Check if the user already saved contact details. If so, then show
the form populated with those details, to let user change them.
"""
try:
contact = Contact.objects.get(user=self.request.user)
return form_class(instance=contact, **self.get_form_kwargs())
except Contact.DoesNotExist:
return form_class(**self.get_form_kwargs())
def form_valid(self, form):
form.instance.user = self.request.user
form.save()
return super(ContactView, self).form_valid(form)
您甚至不需要在此示例的 URL 中使用 pk
,因为该对象是通过 user
一对一字段从数据库中检索的。如果您有类似的情况,其中要创建/更新的模型与用户具有唯一的关系,那就很容易了。
希望这对某人有所帮助...
干杯。
【讨论】:
调用return super(ContactView, self).form_valid(form)
将涉及 save() 已保存的表单对象。
完美,这很有用,所以我可以避免将用户 ID 放在 url 中!
如果省略 **self.get_form_kwargs()
会发生什么?对我来说,这条线 form_class(instance=contact, **self.get_form_kwargs())
产生了一些错误,说 instance kwarg got multiple values。Django:如何使用动态(非模型)数据预填充 FormView?
】Django:如何使用动态(非模型)数据预填充FormView?【英文标题】:Django:Howtopre-populateFormViewwithdynamic(non-model)data?【发布时间】:2014-03-3118:00:20【问题描述】:我有一个FormView视图,使用get_context_data()提供了一些额外的GET上下文... 查看详情
Django mixin 和 FormView 模板与 CBV 混淆
】Djangomixin和FormView模板与CBV混淆【英文标题】:DjangomixinandFormViewtemplateconfusionwithCBV【发布时间】:2019-12-2202:26:05【问题描述】:总的来说,我仍然是mixins的菜鸟,所以我只是想了解这段使用Ajax提交表单的代码中发生了什么。我... 查看详情
重定向到 django FormView 中的下一个 URL
】重定向到djangoFormView中的下一个URL【英文标题】:RedirecttonextURLindjangoFormView【发布时间】:2015-01-1507:16:21【问题描述】:我正在使用Django1.7和Python3.4。我有一个场景,我希望用户在登录后被重定向到另一个视图,如nextGET参数中... 查看详情
使用jquery post时未调用django formview中的post函数
】使用jquerypost时未调用djangoformview中的post函数【英文标题】:postfunctionindjangoformviewnotcalledwhenjquerypostisused【发布时间】:2018-10-0322:24:17【问题描述】:点击“搜索”按钮时,我必须致电SearchView。通过一些打印语句,我可以看到... 查看详情
使用 FormView django 在 form_valid 中渲染模板而不是 success_url
】使用FormViewdjango在form_valid中渲染模板而不是success_url【英文标题】:Renderatemplateinsteadasuccess_urlinform_validwithFormViewdjango【发布时间】:2015-08-2423:06:19【问题描述】:正如标题所说:我需要在提交表单后渲染一个模板,这个表单是... 查看详情
python基于formview类的django视图示例(代码片段)
当包含在其他模板中时,Django 通用 FormView 不显示
】当包含在其他模板中时,Django通用FormView不显示【英文标题】:DjangogenericFormViewnotshowingwhenincludedinothertemplate【发布时间】:2018-12-0514:40:21【问题描述】:首先,目前的工作是什么:我在forms.py中定义了一个表单:classEnrollForm(for... 查看详情
将参数传递给FormView Django中的表单
】将参数传递给FormViewDjango中的表单【英文标题】:passingaparametertoaforminFormViewDjango【发布时间】:2018-12-1119:22:53【问题描述】:我有一个名为MyForm的表单。我覆盖了__init__()方法。现在我在MyFormView中创建这个表单时需要传递request... 查看详情
MFC中FormView和Dialog有啥区别?
】MFC中FormView和Dialog有啥区别?【英文标题】:WhatarethedifferencesbetweenFormViewandDialoginMFC?MFC中FormView和Dialog有什么区别?【发布时间】:2013-01-0404:09:56【问题描述】:MFC中FormView和Dialog有什么区别?任何人都可以建议何时使用FormView... 查看详情
使用 FormView 和 ModelForm 时如何在模板上获取 non_field_errors
】使用FormView和ModelForm时如何在模板上获取non_field_errors【英文标题】:Howtogetnon_field_errorsontemplatewhenusingFormViewandModelForm【发布时间】:2014-08-1319:56:42【问题描述】:我正在使用FormView和ModelForm来处理注册表单。如果电子邮件重复... 查看详情
FORMVIEW 和 GET
】FORMVIEW和GET【英文标题】:FORMVIEWandGET【发布时间】:2018-06-2622:02:24【问题描述】:我正在尝试清理FORMVIEW,但收效甚微。我有以下表格:表格...classBookRequestNumberSearch(forms.Form):q=forms.IntegerField(required=True)def__init__(self,*args,**kwargs)... 查看详情
Django递归模型
】Django递归模型【英文标题】:Djangorecursivemodel【发布时间】:2018-05-1219:09:43【问题描述】:我正在使用django为我的项目和文件制作自己的“云服务器”。我正在尝试创建树文件结构,但我不知道如何做到这一点。以及如何制作... 查看详情
Django 内连接查询集
】Django内连接查询集【英文标题】:DjangoInnerJoinQueryset【发布时间】:2013-06-2621:26:33【问题描述】:我正在使用Django,我需要使用两个内部连接来执行查询集。我有三个模型A、B和C,我想在psql中进行如下查询:SELECTDISTINCTaFROMAINNE... 查看详情
在 Django 中屏蔽密码
...一的问题是在输入密码时我无法屏蔽密码。Views.pyclassLoginFormView(FormView):template_name=\'Login/login-page.html\'form_class= 查看详情
在 Django 中,如何在提交 CreateView 时重定向到 UpdateView?
...发布时间】:2019-09-0721:55:09【问题描述】:我创建了一个FormView和模板HTML,我将使用它们来创建和更新模型中的记录。但是,我无法弄清楚如何将CreateView设置为重定向到正在创建的新 查看详情
Django,模型和表单:替换“此字段为必填项”消息
】Django,模型和表单:替换“此字段为必填项”消息【英文标题】:Django,Models&Forms:replace"Thisfieldisrequired"message【发布时间】:2011-07-2002:02:32【问题描述】:我知道在使用普通Django表单时如何设置自己的自定义错误消息... 查看详情
在 FormView 中找不到控件?
】在FormView中找不到控件?【英文标题】:can\'tfindcontrolinFormView?【发布时间】:2011-08-3115:05:41【问题描述】:我需要在FormView控件中找到这个<a>标签,我需要根据条件删除这个标签,但我无法使用FormView.FindControl方法找... 查看详情
FormView.FindControl():对象引用错误
】FormView.FindControl():对象引用错误【英文标题】:FormView.FindControl():objectreferenceerror【发布时间】:2010-12-0121:58:07【问题描述】:我有一个在tr/td中有几个文本框的表单视图。我正在尝试使用.FindControl方法获取文本框,但它返回nu... 查看详情