i have a small form in my blog detail view and it has a name,last name,email and an image field. the first three work fine but when i add the imagefield in the form, the form wont save from the page but it works from admin page.
this is my views.py:
def campaign_detail_view(request, id):
template_name = 'gngo/campaign-detail.html'
campaign = get_object_or_404(Campaign, id = id)
comments = CampaignForm.objects.filter(campaign=campaign).order_by('-id')
form = FormCamp(request.POST)
if request.method == 'POST':
if form.is_valid():
name = request.POST.get('name')
last = request.POST.get('last')
email = request.POST.get('email')
comment = CampaignForm.objects.create(campaign=campaign,name=name,last=last,email=email)
comment.save()
return redirect('campaign-detail',id=id)
else:
form = FormCamp()
context = {
'campaign':campaign,
'comments':comments,
'form':form,
}
context["object"] = Campaign.objects.get(id = id)
return render(request, template_name, context)
and this is my comment model:
class CampaignForm(models.Model):
campaign = models.ForeignKey(Campaign, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
last = models.CharField(max_length=100)
email = models.EmailField()
image = models.ImageField(upload_to='images')
this is a non user form, so everyone can fill it. please help me understand how to add the ability to upload an image in this form
oh and this the form:
class FormCamp(forms.ModelForm):
class Meta:
model = CampaignForm
fields = ('name','last','email', 'image',)
THANKS ALOT FOR THE ANSWERS AND SUPPORTS
Instead of using the form to validate and then manually extracting the fields again, you should use the save method of your ModelForm and pass request.FILES to your form when creating it.
And as the campaign is not an editable field, it shall be added after creating the object.
def campaign_detail_view(request, id):
template_name = 'gngo/campaign-detail.html'
campaign = get_object_or_404(Campaign, id = id)
comments = CampaignForm.objects.filter(campaign=campaign).order_by('-id')
if request.method == 'POST':
form = FormCamp(request.POST, request.FILES)
if form.is_valid():
campaign_form = form.save(commit=False)
campaign_form.campaign = campaign
campaign_form.save()
return redirect('campaign-detail',id=id)
else:
form = FormCamp()
context = {
'campaign':campaign,
'comments':comments,
'form':form,
}
context["object"] = Campaign.objects.get(id = id)
return render(request, template_name, context)
https://docs.djangoproject.com/en/2.2/topics/forms/modelforms/#the-save-method
https://docs.djangoproject.com/en/2.2/topics/forms/#the-view
Try this:
def campaign_detail_view(request, id):
template_name = 'gngo/campaign-detail.html'
campaign = get_object_or_404(Campaign, id = id)
comments = CampaignForm.objects.filter(campaign=campaign).order_by('-id')
form = FormCamp(request.POST, request.FILES)
if request.method == 'POST':
if form.is_valid():
comment = form.save(commit=False)
comment = CampaignForm.objects.create(campaign=campaign,name=name,last=last,email=email)
comment = request.FILES['image']
comment.save()
return redirect('campaign-detail',id=id)
else:
form = FormCamp()
context = {
'campaign':campaign,
'comments':comments,
'form':form,
}
context["object"] = Campaign.objects.get(id = id)
return render(request, template_name, context)
class FormCamp(forms.ModelForm): to this;
class FormCamp(forms.Form):
Don't forget to add enctype=multipart/form-data in your form in template.
Related
I am kinda like stuck.
I have a BankAccountCreation() and the the form is called in a modal in Django template.
I am trying to get the same for be used for editing. but when I do that my edit button returns an empty form
My view is as below
def employee_info(request, id):
if not request.user.is_authenticated:
return redirect('/')
context = {}
banks = Bank.objects.all()
employee = get_object_or_404(Employee, id = id)
bank_instance = Bank.objects.filter(employee = employee).first()
context = {}
context['employee'] = employee
context['bank'] = bank_instance
context['banks'] = banks
context['title'] = 'profile - {0}'.format(employee.get_full_name)
if request.method == 'GET':
form = BankAccountCreation()
context['form'] = form
return render(request, 'employee/employee_info.html', context)
if request.method == 'POST':
form = BankAccountCreation(data = request.POST)
if form.is_valid():
instance = form.save(commit = False)
employee_id = request.POST.get('employee')
employee_object = employee
instance.employee = employee_object
instance.name = request.POST.get('name')
instance.branch = request.POST.get('branch')
instance.account = request.POST.get('account')
instance.code = request.POST.get('code')
instance.save()
messages.success(request, 'Bank Details Successfully Created for {0}'.format(employee_object.get_full_name), extra_tags = 'alert alert-success alert-dismissible show')
return redirect('employee_info', id=employee.id)
else:
context['form'] = form
messages.error(request, 'Error Updating details for {0}'.format(employee_object.get_full_name), extra_tags = 'alert alert-warning alert-dismissible show')
return redirect('employee_info', id=employee.id)
form = BankAccountCreation()
return render(request, 'employee/employee_info.html', context)
The Bank model has a foreign key to the Employee model
This is my model :
class Card(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
imp_id = models.TextField(null = True)
And here is my view :
def Add(request):
if request.method == 'POST':
form = Add_card(request.POST)
if form.is_valid():
save = form.save(commit = False)
save.user = request.user
save.imp_id = "asd" # I tried to change it here but I failed
save.save()
else:
form = Add_card()
cards = Card.objects.all()
return render(request, 'addcard.html', {'form': form, 'cards' : cards})
How can I change that textfield before save?
you can do it like this
def Add(request):
if request.method == 'POST':
request.POST.imp_id="asd"
form = Add_card(request.POST)
if form.is_valid():
save = form.save(commit = False)
save.user = request.user
save.save()
else:
form = Add_card()
cards = Card.objects.all()
return render(request, 'addcard.html', {'form': form, 'cards' : cards})
The problem could be solved by using default='asd'.
I have a crud application and would like to update the items. I have checked some solutions online which explains that the .update method can't be used like this but for only a queryset. I don't know how to update the information manually. Thanks
views.py
def UpdateReservation(request, pk):
table_exists = Reservation.objects.get(id=pk)
form = ReservationForm(instance=table_exists)
if request.method == "POST":
if request.POST['table']:
request.POST = request.POST.copy()
table_exists = Reservation.objects.get(id=pk)
try:
if table_exists:
time = form['time']
people = form['people']
comment = form['comment']
date_reserved = form['date_reserved']
email = form['email']
phone = form['phone']
first_name = form['first_name']
resrv = table_exists.update(email=email, first_name=first_name, people=people, time=time, date_reserved=date_reserved, comment=comment, table=table_exists)
resrv.save()
messages.success(request, "you have successfully edited.")
return redirect(request.path)
else:
messages.error(request, "Unable to edit.")
return redirect(request.path)
except Exception as e:
messages.error(request, "Unknown error" + str(e))
return redirect(request.path)
context = {"form":form}
return render(request, "dashboard/super/admin/update_reserve.html", context)
After trying that, it returns the error, Unknown error'Reservation' object has no attribute 'update'
It is better to validate the form and update the individual fields with respective values and then save the object. The view should be as follows:
from django.shortcuts import get_object_or_404
def UpdateReservation(request, pk):
table_exists = get_object_or_404(Reservation, id=pk)
form = ReservationForm(instance=table_exists)
if request.method == "POST":
form = ReservationForm(request.POST, instance=table_exists)
if form.is_valid():
time = form['time']
people = form['people']
comment = form['comment']
date_reserved = form['date_reserved']
email = form['email']
phone = form['phone']
first_name = form['first_name']
table_exists.email = email
table_exists.first_name = first_name
table_exists.people = people
table_exists.time = time
table_exists.date_reserved = date_reserved
table_exists.comment = comment
table_exists.save()
messages.success(request, "you have successfully edited.")
return redirect(request.path)
else:
messages.error(request, "Unable to edit.")
return redirect(request.path)
context = {"form": form}
return render(request, "dashboard/super/admin/update_reserve.html", context)
You should use model like this:
table_exists = Reservation.objects.get(id=pk)
table_exists.email = email
table_exists.first_name = first_name
table_exists.people = people
table_exists.time = time
table_exists.date_reserved = date_reserved
table_exists.comment = comment
table_exists.table = table_exists
table_exists.save()
Hey guys how can i set initial value in my form field, let say the user click "BidForm" in the search form, i want the BidForm value will be the value of ProjectName in the other form...
here's my code in my search views
def search_views(request):
project_list = ProjectNameInviToBid.objects.all()
query = request.GET.get('query')
if query:
project_list = project_list.filter(ProjectName__icontains=query)
context = {
'project_list': project_list
}
return render(request, 'content/search_views.html', context)
and my other views
def project_name_details(request, sid):
majordetails = ProjectNameInviToBid.objects.get(id=sid)
if request.method == 'POST':
form = invitoBidForm(request.POST, request.FILES)
form.fields['ProjectName'].initial = majordetails
if form.is_valid():
form.save()
messages.success(request, 'File has been Uploaded')
else:
form = invitoBidForm()
args = {
'majordetails': majordetails,
'form': form
}
return render(request,'content/invitoBid/bacadmininvitoBid.html', args)
my form.py
class invitoBidForm(ModelForm):
class Meta:
model = InviToBid
fields = ('ProjectName','NameOfFile', 'Contract_No', 'Bid_Opening',
'Pre_Bid_Conference', 'Non_Refundable_Bidder_Fee',
'Delivery_Period',
'Pdf_fileinvi',)
and my models.py
class ProjectNameInviToBid(models.Model):
ProjectName = models.CharField(max_length=255, verbose_name='Project Name', null=True)
DateCreated = models.DateField(auto_now=True)
def __str__(self):
return self.ProjectName
class InviToBid(models.Model):
today = date.today()
ProjectName = models.ForeignKey('ProjectNameInviToBid', on_delete=models.CASCADE)
NameOfFile = models.CharField(max_length=255, verbose_name='Name of File')
Contract_No = models.IntegerField(verbose_name='Contract No')
def __str__(self):
return self.NameOfFile
First, I shall praise your documentation. Most people fail to provide the important code.
You can add something like this to your code here that will do what you require.
An example from my own code
if request.method == 'GET' and request.user.is_authenticated:
study = Study.objects.get(pk=studyID)
form = ContactForm(initial={'from_email': request.user.email, 'subject': "Study: " + study.name ,'message': study_message.format(request.user.get_short_name(), request.user.get_full_name())})
How you should change your code
Change your code in your other views from this:
else:
form = invitoBidForm()
to
else:
form = invitoBidForm(initial={'ProjectName': <wherever your project name comes from>})
views.py
def patient_num(request):
if request.method == 'POST':
form = EditToBeSaveForm(request.POST)
if form.is_valid():
num = form.cleaned_data['病人编号']
new_p = Patient.objects.get(p_number=num)
if new_p:
new_p.p_name = form.cleaned_data['姓名']
new_p.p_sex = form.cleaned_data['性别']
new_p.p_age = form.cleaned_data['年龄']
new_p.p_tel_number = form.cleaned_data['电话号码']
new_p.save()
return render(request, 'polls/patient_edit.html')
else:
form = EditToBeSaveForm()
return render(request, 'polls/patient_num.html', {'form': form})
models.py
class Patient(models.Model):
sex_choice = (
('男', '男'),
('女', '女'),
)
p_name = models.CharField(max_length=100, default='template')
p_age = models.IntegerField(default=0)
p_number = models.IntegerField(default=0)
p_tel_number = models.IntegerField(default=0)
p_sex = models.CharField(choices=sex_choice, max_length=2, default='男')
forms.py
class EditForm(forms.Form):
病人编号 = forms.IntegerField()
class EditToBeSaveForm(forms.Form):
sex_choice = (
('male', '男'),
('female', '女'),
)
病人编号 = forms.IntegerField(label='你要修改的病人编号')
姓名 = forms.CharField(max_length=100)
年龄 = forms.IntegerField()
电话号码 = forms.IntegerField()
性别 = forms.ChoiceField(choices=sex_choice)
after i populate the form and submit it, the view didn't update the database instance,why?
i can do it one by one in shell as below.
new confuse!when i populate the form with invalid value,for example, an inexistent id of Patient object,it will still render the template,why?
It seems to me your problem is that you never reach the code under the if form.is_valid() of your patient_num view. Try to add some prints after the if form.is_valid() clause and make sure your form is valid. It is expected that your model will not be updated if your form is not valid.
Your problem here that you are passing request to form instead request.POST
form = EditToBeSaveForm(request.POST)
i put some 'print stuff' in my view and disvocer sth:
def patient_num(request):
print(111)
if request.method == 'POST':
print(2222)
form = EditToBeSaveForm(request.POST)
if form.is_valid():
print(3333)
num = form.cleaned_data['病人编号']
new_p = Patient.objects.get(p_number=num)
if new_p:
print(4444)
new_p.p_name = form.cleaned_data['姓名']
new_p.p_sex = form.cleaned_data['性别']
new_p.p_age = form.cleaned_data['年龄']
new_p.p_tel_number = form.cleaned_data['电话号码']
new_p.save()
return render(request, 'polls/patient_edit.html')
else:
form = EditToBeSaveForm()
return render(request, 'polls/patient_num.html', {'form': form})
i can only see 111 in the shell output.it seems that the view even didn't receive the post request.and i check my html file and find the problem.the form's destination direct to another view function…… it's so stupid, i'm sorry for waste your time !