laj*_*rre 26 django django-forms django-views
我无法弄清楚如何使用ModelForm的FormView,这样它更新一个已经存在的实例?
此URL上的表单POST: r'/object/(?P<pk>)/'
我使用a ModelForm(而不是直接使用UpdateView),因为其中一个字段是必需的,我对它执行清理.
我基本上喜欢instance=...在FormView(在POST时)初始化表单时提供kwarg ,以便它绑定到在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 ...
Run Code Online (Sandbox Code Playgroud)
Jos*_*iño 28
对于这个主题的任何进一步的访问者,是的,你可以做一个FormView像a CreateView和a 一样的行为UpdateView.这个,尽管有其他用户的一些意见,如果你想要一个Web表单的单个表单/ URL /页面来保存一些用户数据可以是很有意义的,这些用户数据可以是可选的,但只需要保存一次.您不希望有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)
Run Code Online (Sandbox Code Playgroud)
所以,你写一个ModelFormfor,就像这样:
from django import forms
from .models import Contact
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
exclude = ('user',) # We'll set the user later.
Run Code Online (Sandbox Code Playgroud)
您的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)
Run Code Online (Sandbox Code Playgroud)
您甚至不需要pk在此示例的URL中使用a ,因为通过user一对一字段从DB检索对象.如果您有一个类似于此的案例,其中要创建/更新的模型与用户具有唯一的关系,则非常容易.
希望这有助于某人......
干杯.
jpr*_*itt 24
经过与你的一些讨论,我仍然不明白为什么你不能使用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())
Run Code Online (Sandbox Code Playgroud)
当然,如果我误解你,请告诉我.你应该可以让它工作.
| 归档时间: |
|
| 查看次数: |
25769 次 |
| 最近记录: |