I'm trying to refactor my code into class-based views, and I'm having trouble understanding how to return/render at the end. I'm trying to render the form with the supplied POST data on success (or fail), with an appropriate confirmation message, so that it can be updated. Here's some example code, with comments showing what I want to return (where I don't know how):
from django.views.generic import CreateView, UpdateView
from my_app.forms import ProductCreateForm
from my_app.models import Product
from django.contrib.auth.models import User
class ProductCreate(CreateView):
"""Simple CreateView to create a Product with ForeignKey relation to User"""
model = Product
form_class = ProductCreateForm
template = 'product_create.html'
def form_valid(self, form):
user = User.objects.filter(username=form.cleaned_data['user_email']).first()
if user is None:
messages.error("Invalid user email specified")
return some http response here...
#How to I render the page again, but with the data already in the
#form we don't have to re-enter it all?
form.save()
messages.info("Successfully saved the product!")
return some http response here...
#How do I redirect to the UpdateView here with the Product instance
#already in the form?
class ProductUpdate(UpdateView):
model = Product
form_class = ProductCreateForm
template = 'product_create.html'
You shouldn't be doing any of that there. The view is already taking care of calling the validation methods and redisplaying the form if validation fails; form_valid
is only called if the form is already valid. Your user check should go into the form itself:
class ProductCreateForm(forms.ModelForm):
...
def clean_user_email(self):
user = User.objects.filter(username=self.cleaned_data['user_email']).first()
if user is None:
raise forms.ValidationError("Invalid user email specified")
return user
For the second part, redirecting to the update view, you can do that by defining the get_success_url
method; what it returns depends on the URL you have defined for the ProductUpdate view, but assuming that URL takes an id
argument it would be something like this:
class ProductCreate(CreateView):
def get_success_url(self):
return reverse('product_update', kwargs={'id': self.instance.pk})
That leaves your form_valid
method only needing to set the message on success, and you don't even need to do that if you use the SuccessMessageMixin from contrib.messages.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.