I try to update my record but in place of updating it displays a message saying the record already exists.
here is the logic I m executing :
#login_required
def cylinderUpdateView(request,pk):
if not request.user.is_superuser:
return redirect('index')
obj=CylinderEntry.objects.get(id=pk)
form=CylinderEntryForm(instance=obj)
if request.method=='POST':
form=CylinderEntryForm(data=request.POST)
if form.is_valid():
obj=form.save(commit=False)
obj=form.save()
return redirect(cylinderListView)
return render(request,'entry/cylinderentry_form.html',locals())
In case of a POST request you have initialized the form as:
if request.method=='POST':
form=CylinderEntryForm(data=request.POST)
Here you haven't specified the instance like you did in case of a GET request so only the data submitted from the form is considered you need to specify the instance in this case too:
if request.method=='POST':
form=CylinderEntryForm(data=request.POST, instance=obj)
If you want to update an object with a ModelForm, you should pass that instance with the instance=… parameter:
#login_required
def cylinderUpdateView(request,pk):
if not request.user.is_superuser:
return redirect('index')
obj = CylinderEntry.objects.get(id=pk)
if request.method=='POST':
# pass the instance ↓
form = CylinderEntryForm(data=request.POST, instance=obj)
if form.is_valid():
form.save()
return redirect(cylinderListView)
else:
form = CylinderEntryForm(instance=obj)
return render(request,'entry/cylinderentry_form.html',locals())
Related
def create_new(request):
if request.method == 'POST':
form = ArticleForm(request.POST)
form.id_author = request.user.id
if form.is_valid():
form.save()
return redirect('home')
return render(request, 'main/create_new.html')
def create_new(request):
if request.method == 'POST':
form = ArticleForm(request.POST)
if form.is_valid():
article = form.save(commit=False)
article.author = request.user
article.save()
return redirect('home')
return render(request, 'main/create_new.html')
Is it possible to change the 2nd code into the first code??
it shows some kind of error
No, at first you always need to check whether the form is valid or not, then after you can save the form with commit=False which creates a temporary instance, then you should assign any value in that instance.
The second approach is correct.
This is my update views:
def EditDoctor(request,slug=None):
if request.method == "POST":
obj = get_object_or_404(Doctor,slug=slug)
form = DoctorUpdateFrom(request.POST,instance=obj)
if form.is_valid():
form.save()
return redirect('hospital:all-doctor')
else:
form = DoctorUpdateFrom()
context = {'doctor_form':form}
return render (request,'hospital/edit-doctor.html', context)
The main problems I am not seeing any existing value in my forms. it's just rendering an empty forms.
You need to pass the instance to the form in case of a GET request as well:
def EditDoctor(request,slug=None):
obj = get_object_or_404(Doctor,slug=slug) # 🖘 fetch the object for both paths
if request.method == "POST":
form = DoctorUpdateFrom(request.POST,instance=obj)
if form.is_valid():
form.save()
return redirect('hospital:all-doctor')
else:
form = DoctorUpdateFrom(instance=obj) # 🖘 pass the instance to edit
context = {'doctor_form':form}
return render (request,'hospital/edit-doctor.html', context)
I'm new at Python & Django and currently struggling right now.
I created an update/edit form with Django Model forms, but it just doesn't prepopulate the form fields and post it to the database at the same time.
I think the problem lies in form = AdvertForm(request.POST or None, request.FILES or None, instance=form).
Without request.POST or None, request.FILES or None, it does prepopulate the fields but won't update the data to database.
Here's my views.py:
def update_advert(request, id):
if not request.user.is_authenticated():
return render(request, 'forum/login.html')
else:
form = get_object_or_404(Advert, pk=id)
if request.method == 'POST':
form = AdvertForm(request.POST or None, request.FILES or None, instance=form)
if form.is_valid():
form = form.save(commit=False)
form.user = request.user
form.save()
return redirect('forum:user_account')
else:
form = AdvertForm(instance=form)
context = {'form': form}
return render(request, 'forum/update_advert.html', context)
In the moment it looks like this, when I try to open the update form:
opening the form --> not prepopulated :(
According to https://docs.djangoproject.com/en/dev/ref/forms/api/#dynamic-initial-values, you can use the initial attribute when instantiating forms in order to prepropulate your forms.
def update_advert(request, id):
if not request.user.is_authenticated():
return render(request, 'forum/login.html')
else:
advert_obj = get_object_or_404(Advert, pk=id)
if request.method == 'POST':
form = AdvertForm(request.POST or None, request.FILES or None, instance=advert_obj)
if form.is_valid():
form.save()
return redirect('forum:user_account')
else:
# Prepopulation happens here:
data = {"some_field": advert_obj.some_val} # Insert all the values of advert_obj here and their field names as keys.
form = AdvertForm(initial=data)
context = {'form': form}
return render(request, 'forum/update_advert.html', context)
In your AdvertForm, put this code:
class AdvertForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(AdvertForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
instance = super(AdvertForm, self).save(commit=False)
instance.user = self.request.user
if commit:
instance.save()
return instance
The overriding save method simply does what you were doing in the views to link up the request.user to the instance, however I have placed that code in the form class to keep your views simple.
Also, I can see one confusing (but not vital) issue - you have mixed up the variable names.
When calling form = get_object_or_404(Advert, pk=id), this should return to a variable name such as advert or something similar. Not form as that can be confusing as we are returning a model object not a form. Similarly, form.save(commit=False) returns an "instance" not a model form. This won't solve your problem but should be pointed out for more clarification on what exactly is being returned and how you should then name your variables.
Im trying to get the value form a post in django but it pass an empty field `def PersonEmail(request):
Im trying to get the value form a post in django but it pass an empty field `def PersonEmail(request):
if request.method == "POST":
form1 = PersonForm(request.POST, prefix="form1")
form2 = EmailForm(request.POST, prefix="form2")
name = form2['email'].value
return HttpResponse(name)
else:
form1 = PersonForm()
form2 = EmailForm()
return render(request, 'CreatePersonEmail.html', locals())`
but when i separate them i.e.
Im trying to get the value form a post in django but it pass an empty field `def PersonEmail(request):
if request.method == "POST":
# form1 = PersonForm(request.POST, prefix="form1")
form2 = EmailForm(request.POST, prefix="form2")
name = form2['email'].value
return HttpResponse(name)
else:
form1 = PersonForm()
form2 = EmailForm()
return render(request, 'CreatePersonEmail.html', locals())`
it gives me the value of the field.
Why? and how can i make it to obtain the values of both forms fields?
Basically, you're doing it wrong.
Firstly, you need to check if the form is valid. Users could type any crap in, you don't want to let them do that:
if request.method == "POST":
form = MyForm(request.POST)
if form.is_valid():
# Now you can access the fields:
name = form.cleaned_data['name']
If the form isn't valid, just pass it back to render() and it will show the errors.
Also, don't do this:
return render(request, 'CreatePersonEmail.html', locals())`
Build your context dictionary properly, don't use locals(), it's hacky and you pollute your context.
So a full view might look like this (taken from django docs and changed a bit:
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
name = form.cleaned_data['name']
return render(request, 'some_page.html', {'name': name})
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'name.html', {'form': form})
You need to use the prefix both times you instantiate the forms; both on GET and on POST.
Also, you get values from the form's cleaned_data dict, not from the field.
Let's say I have a form for adding/editing products (with field 'user' being a foreign key to my User) triggered from two separate view functions - add/edit :
def product_add(request):
userprofile = UserProfile.objects.get(user=request.user)
if request.method == 'POST':
form = ProductAddForm(request.POST, request.FILES,)
if form.is_valid():
form.save(user=request.user)
else:
form = ProductAddForm()
return render_to_response('products/product_add.html', {
'form':form, 'user':request.user,
}, context_instance=RequestContext(request))
def product_edit(request, id):
product = get_object_or_404(Product, id=id, user=request.user)
if product.user.id!=request.user.id:
raise Http404
if request.method == 'POST':
form = ProductAddForm(request.POST, request.FILES, instance=product)
if form.is_valid():
form.save(user=request.user)
else:
form = ProductAddForm(instance=product)
return render_to_response('products/product_edit.html', {
'form':form, 'user':request.user,
}, context_instance=RequestContext(request))
The form's save method looks as follows :
def save(self, user, *args, **kwargs):
self.instance.user = user
post = super(ProductAddForm, self).save(*args, **kwargs)
post.save()
Can somebody tell me what's happening in this save method step by step ?Why do we call super on this form and what is the difference in whole processing when we edit and save new product if function call is the same ?
self.instance.user = user
Save the user argument into the self.instance object's user attribute
post = super(ProductAddForm, self).save(*args, **kwargs)
Invoke the superclass save method to get a resulting object.
post.save()
Save the resulting object. This may be needless, or it may be essential, depending on the arguments to save.
See http://docs.djangoproject.com/en/1.2/topics/forms/modelforms/#the-save-method. If commit is False, then the post object has not been saved to the database.