Can't work modal form with method POST in Django - django

Thats my first project in Django. I want to make table and add items with modal form. I use Mysql database. items which addes manually from phpmyadmin already exist on table but when i try add from modal form it cant added.
views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Client
def viewpost(request):
post_list = Client.objects.all()
context = {
'posts': post_list
}
return render(request, 'mysite/viewtable.html', context)
def add_client(request):
if request.method == 'POST':
post = Client()
post.name = request.POST.get('name')
post.surname = request.POST.get('surname')
post.address = request.POST.get('address')
post.gender = request.POST.get('gender')
post.age = request.POST.get('age')
post.save()
return render(request, 'mysite/viewtable.html')
else:
return render(request, 'mysite/viewtable.html')
url.py:
from django.urls import path
from . import views
urlpatterns = {
path('viewtable/', views.viewpost, name='viewpost'),
path('viewtable/#add_data_Modal', views.add_client, name='add_client'),
}

Before the table and modal form didnt work together. If table worked then modal form didnt add to database or conversely. Now the're work together: Modal form add to database then table show data on page. But when i refresh page data add to databse twice.
views.py:
def viewpost(request):
post_list = Persona.objects.all()
context = {
'posts': post_list
}
if request.method == 'POST':
if request.POST.get('name') and request.POST.get('surname') and request.POST.get('address'):
post = Client()
post.name = request.POST.get('name')
post.surname = request.POST.get('surname')
post.address = request.POST.get('address')
post.age = request.POST.get('age')
post.save()
return render(request, 'mysite/viewtable.html', context)
else:
return render(request, 'mysite/viewtable.html')

Thats SOLVED. Here's view
def viewpost(request):
post_list = Persona.objects.all()
if request.method == 'POST':
if request.POST.get('name') and request.POST.get('surname') and
request.POST.get('address'):
post = Persona()
post.name = request.POST.get('name')
post.surname = request.POST.get('surname')
post.address = request.POST.get('address')
post.age = request.POST.get('age')
post.save()
return HttpResponseRedirect('/viewtable')
else:
return render(request, 'mysite/viewtabel.html', {'posts': post_list}

Related

Django- how to save formset model

I have the following view code
def edit_pal(request,pal_id):
pals=palabout.objects.get(id=pal_id)
form2=editpalForm(request.POST or None,instance=pals)
RecipeIngredientFormset = modelformset_factory(palabout, form=editspalForm,extra=0)
formset = RecipeIngredientFormset(request.POST or None,prefix=pals)
context={
"formset": formset,
"form2":form2,
"pals":pals
}
if request.method == 'POST':
if form2.is_valid() and formset.is_valid():
parent = form2.save(commit=False)
parent.save()
for form in formset:
child = form.save(commit=False)
child.recipe = parent
child.save()
context['message']='Data Saved'
return redirect('hod:manage_pal')
return render(request,"edit-pal.html",context)
I remove formset.is_validso it's working but it's not working when i added more for used formset.is_validso why isn't saving file or details show? Can anyone help this?
I think you need to only redirect if the forms are valid so try this view:
from django.shortcuts import get_object_or_404
def edit_pal(request,pal_id):
pals=get_object_or_404(palabout,id=pal_id)
if request.method == 'POST':
form2=editpalForm(request.POST,instance=pals)
RecipeIngredientFormset = modelformset_factory(palabout, form=editspalForm,extra=0)
formset = RecipeIngredientFormset(request.POST,prefix=pals)
if form2.is_valid() and formset.is_valid():
parent = form2.save(commit=False)
parent.save()
for form in formset:
child = form.save(commit=False)
child.recipe = parent
child.save()
context['message']='Data Saved'
return redirect('hod:manage_pal')
else: # if the form is not valid
return redirect("hod:some_error_page")
else: # GET request
RecipeIngredientFormset = modelformset_factory(palabout, form=editspalForm,extra=0)
formset = RecipeIngredientFormset(prefix=pals)
context={
"formset": formset,
"form2":editpalForm(instance=pals),
"pals":pals
}
return render(request,"edit-pal.html",context)

After getting a form.cleaned_data from POST how to pass it to another view?

as the title says: how can I (in DJANGO) get data from a form in a view (in the code below is the ALIMENTA2 view) and then use that as context in another class-based view (GMO, which is a PDF report built with easy_pdf)?
I'm a noob at django, but I've tried redirect and render... I don't seem to understand exactly what I'm doing, really hahaha
views.py
def alimenta2(request):
if request.method == 'POST':
form = AlimentaForm(request.POST)
if form.is_valid():
day = form.cleaned_data['sign_date']
shipper = form.cleaned_data['shipper']
context = {'day': day, 'shipper': shipper}
#HERE IS THE PROBLEM, I WANT TO PASS THE CONTEXT:
return redirect('GMO', context=context)
else: form = AlimentaForm()
return render(request, 'agroex/alimenta2.html', {'form':form})
class GMO(PDFTemplateView):
template_name = 'agroex/gmo.html'
def get_context_data(self, **kwargs):
context = super(GMO, self).get_context_data(
pagesize='A4',
title='NON-GMO Certificate',
day=self.day,
**kwargs
)
urls.py
urlpatterns = [
path('', views.agroex, name='agroex'),
path('alimenta2/', views.alimenta2, name='alimenta2'),
path('alimenta2/GMO/', views.GMO.as_view(), name='GMO'),
]
You can store the variables in session and then retrieve in the other view, like this:
def alimenta2(request):
if request.method == 'POST':
form = AlimentaForm(request.POST)
if form.is_valid():
day = form.cleaned_data['sign_date']
shipper = form.cleaned_data['shipper']
request.session['day'] = day
request.session['shipper_id'] = shipper.id
return redirect('GMO')
else:
form = AlimentaForm()
return render(request, 'agroex/alimenta2.html', {'form':form})
class GMO(PDFTemplateView):
template_name = 'agroex/gmo.html'
def get_context_data(self, **kwargs):
day = request.session['day']
shipper_id = self.request.session['shipper_id']
shipper = Shipper.objects.get(id=shipper_id)
context = super(GMO, self).get_context_data(
pagesize='A4',
title='NON-GMO Certificate',
day=day,
shipper=shipper,
**kwargs
)
You can retrieve the data on a form field like this if using a class-based view:
class RecordUpdatePage(UpdateView):
model = DashboardModel
template_name = "dashboard/record_update.html"
form_class = RecordForm
success_url = [your success url]
def get_context_data(self, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
var = form['my_form_field_name']
print(var.value())
# return a new context if you want
context['modified_field'] = int(var.value()) + 1000
return context
As this is a CBV example, you would define this class as a view in urls.py:
path('dashboard/record_update/<str:pk>/', RecordUpdatePage.as_view(), name= 'record_update'),

Submit two forms in a single submit in Django

I have two forms in template. At the moment I have two submit buttons.
Would like to combine those to a single submit button.
Below code is now updating only one form, that's AnswerForm.
How i can update AnswerReplyForm along with that?
class AnswerView(ObjectEditView):
form_class = forms.AnswerReplyForm
answer_form = forms.AnswerForm
model = AnswerReply
def get(self, request, pk):
answer = get_object_or_404(Answer, pk = pk)
answer_reply = AnswerReply.objects.filter(answer_id = pk).order_by('-id')
self.answer_form = self.answer_form(instance=answer)
return render(request, 'helpdesk/answer.html', {
'answer': answer,
"answer_reply" : answer_reply,
'obj_type': 'answer reply',
'form': self.form_class,
"form2":self.answer_form,
"pre_reply_from" : self.predefined_reply_form
})
def post(self, request, pk, *args, **kwargs):
answer = get_object_or_404(Answer, id=pk)
answer_reply = AnswerReply.objects.filter(answer_id = pk).order_by('-id')
self.answer_form = self.answer_form(instance=answer)
obj = self.model()
obj = self.alter_obj(obj, request, args, kwargs)
form = self.form_class(request.POST, request.FILES, instance=obj)
if form.is_valid():
form.instance.answer_id = pk
obj_created = not form.instance.pk
obj = form.save()
return render(request, 'helpdesk/answer.html', {
'answer': answer,
"answer_reply" : answer_reply,
'obj_type': 'answer reply',
'form': self.form_class,
"form2":self.answer_form,
})
In general:
if request.method == 'POST':
form_1 = FormOne(request.POST)
form_2 = FormTwo(request.POST)
if form_1.is_valid() and form_2.is_valid():
form_1.save()
form_2.save()
return #Write your return here, something like HttpResposeRedirect or whatever you need to do after saving both form successfully
else:
form_1 = FormOne()
form_2 = FormTwo()
context = {
'form1': form_1,
'form2': form_2
}
return render(request, 'template.html', context)
In your template file
<form>
{{ form1 }}
{{ form2 }}
<input type="submit" value= "submit">
</form>
It will work.
It's better to define a structure for each one (View, route and template)
Then, based on desired condition, display one of the structures (redirect to one of them):
for example decision view:
def decisionView(request):
route = '/route/1'
if condition:
route = '/route/2'
return redirect(route)
i hope this could help you

Django - Having two views in same url

I am making a website in django and in my homepage I want to show the list of my recent blog post and a few blocks below I want to make a simple contact form. The blog and the contact form separately are working fine. But I want to include them in the same page(obviously in the same url).
The views.py is:
from .forms import NameForm
def get_name(request):
if request.method == 'POST':
form = NameForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/thanks/')
else:
form = NameForm()
return render(request, 'personal/index.html', {'form': form})
If you want to look at the forms.py then :
from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
The urlpattern in urls.py of my homepage is:
urlpatterns = [
url(r'^$', ListView.as_view(
queryset=Post.objects.all().order_by("-date")[:2],
template_name="personal/index.html")),
url(r'^$', views.get_name, name='contact'),
]
With this urlpatter the list of blog post shows up perfectly but the contact form doesn't show up. But with the below urlpattern contact form shows up but blog posts doesn't show up.
urlpatterns = [
url(r'^$', views.get_name, name='contact'),
url(r'^$', ListView.as_view(
queryset=Post.objects.all().order_by("-date")[:2],
template_name="personal/index.html")),
]
I want to make both of these contents show up in the same page. Please help me. If you need any more information then do tell.
It is not possible to have multiple views for the same URL. You can only have one view for each URL.
In this case, the easiest fix is to update your get_name view so that it includes the posts in the template context.
def get_name(request):
if request.method == 'POST':
form = NameForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/thanks/')
else:
form = NameForm()
post_list = Post.objects.all().order_by("-date")[:2]
return render(request, 'personal/index.html', {'form': form, 'post_list': post_list})
Then remove the url pattern that uses ListView so that get_name handles the requests.
While you cannot do that directly, you could consider your function in views.py to handle the request in a way that when it gets a post request from one model then it initialises the form for the respective model only. For this to happen you will need to assign a name to your button. See below code -
def SignUpLogin(request):
message = ""
Login_message = ""
print(request.POST)
if request.method == 'POST':
if request.POST.get('UserForgotPassword') == 'Sign Up':
form_SignUP_Login = LoginForm()
print("POST request received")
print(request.POST)
form_SignUP=SignUpForm(request.POST)
print(form_SignUP)
if form_SignUP.is_valid():
if request.POST["Password"] != request.POST["Confirm_Password"]:
message = "* Passwords do not match"
#raise forms.ValidationError(('Passwords do not match'), code="PasswordNotMatched")
else:
try:
user = User.objects.get(username=request.POST["Username"])
context= {'form': form_SignUP, 'error':'* Username already taken. Please try different username.'}
return render(request, 'User/SignUp.html', context)
except User.DoesNotExist:
user = User.objects.create_user(request.POST["Username"], request.POST["Email"], request.POST["Password"])
user.first_name = request.POST["First_Name"]
user.last_name = request.POST["Last_Name"]
user.save()
form_SignUP = SignUpModel(Username = request.POST["Username"], First_Name = request.POST["First_Name"], Last_Name = request.POST["Last_Name"], Email = request.POST["Email"], Company_Name = request.POST["Company_Name"], Address = request.POST["Address"], Password = make_password(request.POST["Password"]), Confirm_Password = make_password(request.POST["Confirm_Password"]), Phone_Number = request.POST["Phone_Number"])
form_SignUP.save()
#queryset = SignUpModel.objects.get(Username = request.POST["Username"])
#queryset.Password = "pwd_removed"
#queryset.Confirm_Password = "pwd_removed"
#queryset.save()
#send_email_to_host(request.POST["First_Name"], request.POST["Family_Name"], request.POST["Number_Of_Adults"], request.POST["Number_Of_Kids"], request.POST["Email"])
return redirect(HomePage)
elif request.POST.get('UserLogin') == 'Login':
form_SignUP = SignUpForm()
form_SignUP_Login=LoginForm(request.POST)
if form_SignUP_Login.is_valid():
user = authenticate(username=request.POST["Username"], password=request.POST["Password"])
if user is not None:
print("User authenticated")
return redirect(HomePage)
else:
print("User not authenticated")
form_SignUP_Login = LoginForm()
Login_message = "Username and password combination is not correct"
elif request.POST.get('UserForgotPassword') == 'Forgot Password':
form_SignUP = SignUpForm()
form_SignUP_Login = LoginForm()
else:
form_SignUP = SignUpForm()
form_SignUP_Login = LoginForm()
return render(request, 'User/SignUp.html', {'form' : form_SignUP, "error":message,'form_login' : form_SignUP_Login, "error_login":Login_message})

Django Redirect treating view as a URL

For some reason, Redirect thinks my call to a view 'clients.views.teacher_profile' is a URL, putting it directly in the address bar as shown:
Page Not Found Screenshot
How do I link it to the view and not treat it as a URL?
Note: I have altered some settings to accommodate django-allauth.
My code:
#views.py
def teacher_profile(request, username):
user = get_object_or_404(User, username=username)
context = {
'user':user,
'teacher':user.teacher,
}
return render(request, 'clients/teacher_profile.html', context)
def edit_profile(request):
teacher = get_object_or_404(Teacher, user=request.user)
if request.method == 'POST':
form = TeacherForm(request.POST, instance=teacher)
if form.is_valid():
teacher = form.save(commit=False)
teacher.user = request.user
teacher.save()
return redirect('clients.views.teacher_profile', username=request.user.username)
else:
form = TeacherForm(instance=teacher)
return render(request, 'clients/edit_profile.html', {'form':form})
#urls.py
urlpatterns = [
url(r'^list/$', views.teacher_list, name='teacher_list'),
url(r'^(?P<username>[\w.#+-]+)/$', views.teacher_profile, name='teacher_profile'),
url(r'^accounts/settings/$', views.edit_profile, name='edit_profile'),
]
Don't use the view's module path in the call to redirect; use the name which you explicitly defined in the url pattern.
return redirect('teacher_profile', username=request.user.username)