Hey, I've searched around to do this (particularly this Q: Django edit form based on add form?) but I just can't get it to work.
The problem I'm having is that the form always creates a new object, instead of modifying the existing one.
This is my code:
def new_task(request, task_id=None):
if task_id is not None:
task = Task.objects.get(pk=task_id)
else:
task = Task()
if request.method == 'POST': # If the form has been submitted...
form = TaskForm(request.POST, instance=task)
if form.is_valid():
form.save();
return tasks(request, 'Task #%s created successfully.' % (task.id))
else:
form = TaskForm(instance=task)
return custom_render('user/new_task.html',
{'form': form},
request);
Any clues on what I'm missing? Thanks
Edit: added form definitions.
class TaskForm(ModelForm):
description = CharField(max_length = 1500,
widget= forms.Textarea(attrs={'class':'task-description'}),
required=True)
class Meta:
model = Task
Ok, after a nice night of debugging i found out what the problem was. Quite stupid actually.
The problem was that on submit, task_id was None.
I worked it out by doing:
On the form I added: <form action="{% url App.myapp.views.new_task **task_id** %}"
On my views I added:
return custom_render('user/new_task.html',
{'form': form, 'submit': submit, 'task_id':task.id},
request)
That was it. A newbie mistake. If someone out there knows a nicer way I'm open to suggestions.
Related
Good evening, I am trying to get the id of my model Note that is sent by means of a form, but when I put form.id it tells me that id is not defined, try to get it through the user session but it says that it was not found.
def add_book(request):
template_name = 'books/create_note.html'
book = get_or_create_book(request)
form = NoteForm(request.POST)
if request.method == 'POST' and form.is_valid():
note = Note.objects.get(pk=form.pk)
book.notes.add(note)
form.save()
return redirect('books:book')
return render(request, template_name, {
'form': form,
})
and this is the form
class NoteForm(ModelForm):
class Meta:
model = Note
fields = (
'title', 'nota'
)
labels = {
'title': 'Titulo',
'nota': 'Nota',
}
try creating an instance of my Note model but when it comes time to create it tells me it is empty.
I'm new to Django, but I had similar problems that frustrate me. not sure if I have the hang of it yet, but I think what might be happening is that when you first go to the page there is a GET request, so your if statement misses it. It then it reaches the last line and goes to template_name without the form being assigned so the form never gets a Post requests. In the terminal you can see the POST and GET requests. I ended up also printing out request.method a lot before and after if statements just to help trace what was going on.
else:
form=NoteForm()
Then your return render(request,....
making sure it goes back to the correct html page.
The thing that worked for me eventually was something like
def Search_Page(request):
if request.method=='POST':
form = Search_Page_Form(request.POST)
if form.is_valid():
do some stuff and save the change to the model
return(redirect('mainapp:Evaluate_Page'))
else:
form=Search_Page_Form()
return render(request, 'mainapp/Search_Page.html', {'form': form})
My text posts were working before adding a notification feature but now they aren't, I have a debug print but instead of seeing the post object, I'm seeing the user that posted it. I haven't changed anything other than getting the post id, timesince and the notify function, I've used the exact same method with my picture and video posts and they work fine, so it doesn't make sense to me. I've got a debug print in the notification function to make sure the post type and id have been passed correctly and those indeed show the id and type
views.py
#login_required()
def text_post(request):
if request.method == "POST":
form = TextPostForm(request.POST)
if form.is_valid():
t_post = form.save(commit=False)
t_post.author = request.user
t_post.save()
id = t_post.id
time = timesince
print(t_post) # t_post shows the user instead of the post
followers = list(request.user.followers.all())
notify(followers,
request.user,
f"{request.user.username} posted {time}",
id,
'text'
)
print(t_post)
#redirect to last page
return redirect('home')
else:
form = TextPostForm()
post_type = 'text'
return render(request, 'create_post.html', {'form': form, 'post_type': post_type})
forms.py
class TextPostForm(forms.ModelForm):
class Meta:
model = TextPost
fields = ('description','privacy', 'categories')
I need to update the object with its model form and passed the instance as described in the django doc. However I am having these problems when saving the form:
When I change the title and submit the form, it gives me an error that the image field is required and image field gets blank. However when the image is changed, the title field is not blank and it does not give any error.
If everything works and submits the form, it creates a new snap object instead of updating the instance object.
In the views I tried using both the obj.save() and obj.update(), but nothing helped. Please help me how to solve this problem. I will really appreciate your help Thank you.
form:
class SnapForm(forms.ModelForm):
class Meta:
model = Snap
fields = ['title', 'description', 'image', 'upload_date']
view:
def admin_snap_settings(request, snap_id):
if not request.user.is_admin:
return render(request, 'admin_login_invalid.html')
else:
instance = Snap.objects.get(id=snap_id)
if request.user == instance.user:
if request.method == "POST":
form = SnapForm(request.POST, request.FILES, instance=instance)
if form.is_valid():
form.save()
return HttpResponseRedirect('/custom123user/admin/snapview')
else:
form = SnapForm(instance=instance)
return render(request, 'admin_snap_settings.html', {
'form': form
})
else:
return render(request, 'wrong_user.html')
After hours of debugging and scratching head... I realized that the url of the action for the form was pointing to admin_snap_add() view and not to the admin_snap_settings() view.
Hope this will help someone so dumb as me. If you guys want me to delete this question please inform me. Thank you for your time.
I'm using django to develop a web app. Right now I am trying to make a page that will initially render a blank form and all data objects of a certain model, and then once the user submits the form, will then filter the objects displayed to show those that have the desired attributes.
My form class is as follows
class AreaForm(forms.Form):
seating = forms.IntegerField(label='Seating', default=False)
whiteboards = forms.BooleanField(label='Whiteboards', default=False)
outlets = forms.IntegerField(label='Outlets', default=False)
tables = forms.IntegerField(label='Tables', default=False)
And the view for this page thus far is
def search(request):
if request.method == 'GET':
form = NameForm(request.POST)
if form.is_valid():
# do filtering logic here somehow
return render(request, 'SpotMe/search.html', {'form': form}) # ????
else:
return render(request, 'SpotMe/search.html', {}) # ????
I'm as of yet unsure how to implement the templates page. Am I headed in completely the wrong direction?
To show the form empty and do some logic when user post data, you need to pass the form to the template and it'll render empty if there is not post data.
view.py
def search(request):
form = AreaForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
# do filtering logic here somehow
return render(request, 'SpotMe/search.html', {'form': form})
search.html
.....
{{ form.as_p }}
.....
Based on your reply to my question below your original post, this is an easy solution that will show all data object of a model, and then you can use an input and submit it from a template to filter the results on the same page.
Note: Substitute MODEL for your actually model name. You don't need a form if you are looking to filter results (it is an extra, unnecessary step).
def search(request):
if request.method == 'GET':
if request.GET.get('seating_no'):
seating_no = request.GET.get('seating_no')
queryset = MODEL.objects.filter(seating=seating_no)
else:
queryset = MODEL.objects.all()
return render(request, 'SpotMe/search.html', {'queryset': queryset})
and in your SpotMe/search.html you can have a <form><input name="seating_no" /></form> and submit button that will lead to the same URL, and make the input name(s) into whatever you want to capture via request.GET.get()
I got a form as shown below and I want it to be filled with information from the database when its HTML is rendered. I am passing the id of the Coworker as a parameter for the view.
See code below:
view.py
def EditCoworker(request, id):
form = FormEditCoworker(Coworkers.objects.get(id=id))
if request.method == "POST":
form = FormEditCoworker(request.POST)
if form.is_valid():
form.save()
confirmation_message = "Coworker information updated successfully!"
return render(request, "coworkers/coworkers.html", locals())
else:
return render(request, "coworkers/edit_coworker.html", locals())
return render(request, 'coworkers/edit_coworker.html', locals())
forms.py
class FormEditCoworker(ModelForm):
class Meta:
model = Coworkers
urls.py
url(r'^edit_coworker/(?P<id>[\d]+)$', views.EditCoworker),
Of course the code in my views.py is not right.
Can someone help me on this?
Thanks in advance!
This line
form = FormEditCoworker(Coworkers.objects.get(id=id))
Should be
form = FormEditCoworker(instance=Coworkers.objects.get(id=id))
Although you should really handle the case where the Coworker doesn't exist
form = FormEditCoworker(instance=get_object_or_404(Coworkers, id=id))
EDIT: As Alisdair said, you should also pass the instance keyword arg to the bound form also
instance = get_object_or_404(Coworkers, id=id)
form = FormEditCoworker(instance=instance)
if request.method == "POST":
form = FormEditCoworker(request.POST, instance=instance)