django - How to change existing code to ModelForm instance - python

New to Django and this is my first web application.
I'm having trouble with django's ModelForm feature and I wanted to know:
How do I modify my code so that I can create an instance of ModelForm, and specifically, how can I extract the form data to upload to the backend? I will need to reference this instance at a later time to re-populate the same data in an update_profile view but the updation can only happen once the user is logged in (after signup and profile creation).
For the editing section, do I use pk=some_record.pk? Very confused, any help is appreciated.
The model I'm working with CustomerDetail has a foreign key field customer which references the Customer model:
class CustomerDetail(models.Model):
phone_regex = RegexValidator(regex = r'^\d{10}$', message = "Invalid format! E.g. 4088385778")
date_regex = RegexValidator(regex = r'^(\d{2})[/.-](\d{2})[/.-](\d{2})$', message = "Invalid format! E.g. 05/16/91")
customer = models.OneToOneField(Customer,
on_delete=models.CASCADE,
primary_key=True,)
address = models.CharField(max_length=100)
date_of_birth = models.CharField(validators = [date_regex], max_length = 10, blank = True)
company = models.CharField(max_length=30)
home_phone = models.CharField(validators = [phone_regex], max_length = 10, blank = True)
work_phone = models.CharField(validators = [phone_regex], max_length = 10, blank = True)
def __str__(self):
return str(self.customer)
Here is a snippet of views.py:
def create_profile(request):
if request.POST:
address = request.POST['address']
date_of_birth = request.POST['date_of_birth']
company = request.POST['company']
home_phone = request.POST['home_phone']
work_phone = request.POST['work_phone']
custprofdata = CustomerDetail(address = address, date_of_birth = date_of_birth, company = company, home_phone = home_phone, work_phone = work_phone)
custprofdata.save()
output = {'address': address, 'dateofbirth': date_of_birth, 'company': company, 'homephone': home_phone, 'workphone': work_phone}
return render(request, 'newuser/profile_created.html', output)
else:
return redirect(create_profile)
And here is a snippet of the form part of the respective create_profile.html:
<form action = "{% url 'create_profile' %}" class="create_profile" role="form" method = "post">
{% csrf_token %}
<div class="form-group">
<label for="address" class="col-md-3 control-label">Address</label>
<div class="col-md-9">
<input type="text" class="form-control" name="address" placeholder="777 Park St" />
</div>
</div>
<div class="form-group">
<label for="date-of-birth" class="col-md-3 control-label">Date Of Birth</label>
<div class="col-md-9">
<input type="text" class="form-control" name="date_of_birth" placeholder="09/12/82" />
</div>
</div>
<div class="form-group">
<label for="company" class="col-md-3 control-label">Company</label>
<div class="col-md-9">
<input type="text" class="form-control" name="company" placeholder="Oracle">
</div>
</div>
<div class="form-group">
<label for="home-phone" class="col-md-3 control-label">Home Phone</label>
<div class="col-md-9">
<input type="text" class="form-control" name="home_phone" placeholder="4082992788">
</div>
</div>
<div class="form-group">
<label for="work-phone" class="col-md-3 control-label">Work Phone</label>
<div class="col-md-9">
<input type="text" class="form-control" name="work_phone" placeholder="6690039955">
</div>
</div>
<div class="form-group">
<div class="col-md-offset-3 col-md-9">
<button type = "create" class="btn btn-success" form = "create_profile"> Submit </button>
</div>
</div>
</form>

Implementing a basic ModelForm is just a matter of the following:
from django.forms import ModelForm
from .models import CustomerDetail
class CustomerDetailForm(ModelForm):
class Meta:
model = CustomerDetail
fields = ['address', 'date_of_birth', 'company', 'home_phone', 'work_phone',]
https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/#a-full-example
But I suggest you also switch to using a Class Based View (CBV) - the CreateView will do the same as your existing view with much less code, with an implicit ModelForm (which you can customise by providing your own ModelForm class with form_class = YourFormClass if you want).
https://docs.djangoproject.com/en/1.10/ref/class-based-views/generic-editing/#createview
https://ccbv.co.uk/projects/Django/1.10/django.views.generic.edit/CreateView/

After creating CustomerDetailForm as #John Carter said, you might want to change your view.py to the following
def create_profile(request):
if request.POST:
form = CustomerDetailForm(request.POST)
if form.is_valid():
## save data in database ##
return render(request, 'newuser/profile_created.html', {form:form})
else:
return redirect(create_profile)

Related

How to make time slots(for a particular date and time) not appear after a person has booked it in Django?

I am creating a website in which there is a form where you can book appointments(for doctors)..The issue I am facing is that, if a particular timeslot(for the particular date and time) has been selected it should not appear anymore on the form, but I have no clue on how to do it
The form looks like this(This is returned from the index function in views.py)
<section id="appointment" data-stellar-background-ratio="3">
<div class="container">
<div class="row">
<div class="col-md-6 col-sm-6">
<img src="{% static 'images/appointment-image.jpg' %}" class="img-responsive" alt="">
</div>
<div class="col-md-6 col-sm-6">
<!-- CONTACT FORM HERE -->
<form id="appointment-form" role="form" method="post" action="{% url 'test' %}">
{% csrf_token %}
<!-- SECTION TITLE -->
<div class="section-title wow fadeInUp" data-wow-delay="0.4s">
<h2>Make an appointment</h2>
</div>
<div class="wow fadeInUp" data-wow-delay="0.8s">
<div class="col-md-6 col-sm-6">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Full Name">
</div>
<div class="col-md-6 col-sm-6">
<label for="email">Email</label>
<input type="email" class="form-control" id="email" name="email" placeholder="Your Email">
</div>
<div class="col-md-6 col-sm-6">
<label for="date">Select Date</label>
<input type="date" name="date" value="" class="form-control">
</div>
<div class="col-md-6 col-sm-6">
<label for="select">Select Department</label>
<select class="form-control" name="drop">
{% for entry in items %}
<option>{{ entry.category }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-6 col-sm-6">
<label for="select">Select Time</label>
<select class="form-control" name="drop1">
{% for entry in times %}
<option>{{ entry.time }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-12 col-sm-12">
<label for="telephone">Phone Number</label>
<input type="tel" class="form-control" id="phone" name="phone" placeholder="Phone">
<label for="Message">Additional Message</label>
<textarea class="form-control" rows="5" id="message" name="message" placeholder="Message"></textarea>
<button type="submit" class="form-control" id="cf-submit" name="submit">Submit Button</button>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
The views.py, the test function saves the form(into database) and sends the email:
from django.shortcuts import render, get_object_or_404
from django.core.mail import send_mail
from .models import Form, categories, Doctors, News, timeslot
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth import authenticate
def index(request):
time = timeslot.objects.all()
item = categories.objects.all() # use filter() when you have sth to filter ;)
if request.method == 'POST':
selected_item = get_object_or_404(Item, pk=request.POST.get('item_id'))
selected_item2 = get_object_or_404(time, pk=request.POST.get('time_id'))
# get the user you want (connect for example) in the var "user"
categories.item = selected_item
categories.save()
timeslot.time = selected_item2
timeslot.save()
# Then, do a redirect for example
return render(request, 'website/index.html', {'items':item, 'times':time })
def test(request):
if request.method == "POST":
name=request.POST['name']
email=request.POST['email']
date=request.POST['date']
drop=request.POST.get('drop', False)
time=request.POST.get('drop1', False)
phone=request.POST['phone']
message1=request.POST['message']
message = "Name: "+ name + "\n" + "email: "+ email + "\n" + "Date of appointment: " + date + "\n" + "Time: " + time + "\n" "Service: " + drop + "\n" + "Number: " + phone + "\n" + "Special Message: "+ message1
#send an email
send_mail(
'Make appointment for ' + name, #subject
message, #the msg
email, #from email
['madhavm2002#gmail.com'] #to email
)
#this is used to get the class from the models and then uses the variables assigned here to give value to the variables in models
form=Form(name = name, email = email, date = date, time= time, drop = drop, phone = phone, msg1= message1)
#this used the save method to save the object into the database
form.save()
return render(request, 'website/test.html', {'name':name})
else:
return render(request, 'website/index.html')
The models.py:
from django.db import models
class Form(models.Model):
msg_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=80)
email = models.CharField(max_length=80)
date = models.DateField()
drop = models.CharField(max_length=80)
time = models.TimeField()
phone = models.CharField(max_length=80)
msg1 = models.CharField(max_length=500)
status = models.IntegerField(default = 0)
class categories(models.Model):
category = models.CharField(max_length=80)
class timeslot(models.Model):
time = models.TimeField(max_length=80)
PS: the timeslots looke like 9am,10am,11am...1pm,2pm etc.
The categories give objects like "dental","physio" etc
Do tell how to solve this issue thanks
Essentially you'll need to have something to indicate available timeslots, then with a query joined to your appointments you'd have a condition in your template that that checks if the timeslot already has an appointment (or not) and act accordingly. This is a fairly broad question - see Brian's note.

Django Forms posting not working - Django simply renders the page again

Basically I have set up a form to create organizations. When I hit the Save button, it simply renders the page again - the POST is not working.
See my code below:
models.py
from django.db import models
from accounts.models import User
from datetime import datetime, date
#// ------------ FUNCTIONS -------------//
# Generate Organisation IDs for each organisation
def org_id_generate():
last_org = Organization.objects.all().order_by('org_id').last()
if not last_org:
return 'ORG_001'
else:
last_org_id = last_org.org_id
number_in_id = int(last_org_id[4:7])
new_number_in_id = number_in_id + 1
new_org_id = 'ORG_' + str(new_number_in_id).zfill(3)
return new_org_id
#// ------------ MODELS -------------//
class Organization(models.Model):
org_id = models.CharField(primary_key=True, max_length=7, default=org_id_generate, editable=False)
organization_code = models.CharField(max_length=20)
company_name = models.CharField(verbose_name="Company Name", max_length=60)
legal_name = models.CharField(verbose_name="Legal Name", max_length=100)
industry_distribution = models.BooleanField(verbose_name="Distribution", default=False)
industry_education = models.BooleanField(verbose_name="Education", default=False)
industry_healthcare = models.BooleanField(verbose_name="Healthcare", default=False)
industry_manufacturing = models.BooleanField(verbose_name="Manufacturing", default=False)
industry_retail = models.BooleanField(verbose_name="Retail", default=False)
industry_services = models.BooleanField(verbose_name="Services", default=False)
business_registration_no = models.CharField(verbose_name="Business Registration Number", max_length=15, blank=True)
vat_registration_no = models.CharField(verbose_name="VAT Registration Number", max_length=15, blank=True)
created_date = models.DateTimeField(default=datetime.now)
created_by = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name="Created_By", verbose_name="Created By")
effective_start_date = models.DateField(auto_now_add=False)
effective_end_date = models.DateField(auto_now_add=False, blank=True, null=True)
update_date = models.DateTimeField(default=datetime.now)
last_updated_by = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name="Last_Updated_By", verbose_name="Last Updated By")
def __str__(self):
return self.company_name
forms.py
from django import forms
from organizations.models import Organization
class OrganizationAddForm(forms.ModelForm):
class Meta:
model = Organization
exclude = ['created_date', 'update_date', ]
views.py
from django.shortcuts import get_object_or_404, render, redirect
from organizations.models import Organization
from forms import OrganizationAddForm
from accounts.models import User
from django.contrib.auth.decorators import login_required
#login_required()
def settings(request):
return render(request, 'settings/settings.html')
#login_required()
def organizations_settings(request):
orgs = Organization.objects.all()
context = {
'orgs': orgs,
}
return render(request, 'settings/settings_organizations.html', context)
#login_required
def organization_add(request):
if request.method == 'POST':
user_email = request.user.email
form = OrganizationAddForm(request.POST)
if form.is_valid():
form.organization_code = form.cleaned_data['organization_code']
form.company_name = form.cleaned_data['company_name']
form.legal_name = form.cleaned_data['legal_name']
form.business_registration_no = form.cleaned_data['brn']
form.vat_registration_no = form.cleaned_data['vat']
form.industry_distribution = form.cleaned_data['industry_distribution']
form.industry_education = form.cleaned_data['industry_education']
form.industry_healthcare = form.cleaned_data['industry_healthcare']
form.industry_manufacturing = form.cleaned_data['industry_manufacturing']
form.industry_retail = forms.cleaned_data['industry_retail']
form.industry_services = form.cleaned_data['industry_services']
form.effective_start_date = form.cleaned_data['effective_start_date']
form.effective_end_date = form.cleaned_data['effective_end_date']
form.created_by = form.cleaned_data[user_email]
form.last_updated_by = form.cleaned_data[user_email]
form.save()
return redirect('organizations_settings')
else:
form = OrganizationAddForm()
return render(request, 'settings/add_organization.html', {'form': form})
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.settings, name="settings"),
path('organizations/', views.organizations_settings, name='organizations_settings'),
path('organization_create', views.organization_create, name="organization_create"),
path('organizations/add/', views.organization_add, name="organization_add"),
]
Page Source Code
<!-- Add Organization Form -->
<div class="container form-style">
<i class="fas fa-arrow-left"></i> Back
<div class="form-header">
<h3>Add Organization</h3>
</div>
<form action="{% url 'organization_add' %}" method="POST">
{% csrf_token %}
<div class="container">
<!-- Row 1 -->
<div class="row">
<div class="col-md-4">
<label for="organization_code">Organization Code<span class="star-red">*</span></label>
<input type="text" name="organization_code" class="form-control" required>
</div>
<div class="col-md-4">
<label for="company_name">Organization Name<span class="star-red">*</span></label>
<input type="text" name="company_name" class="form-control" required>
</div>
<div class="col-md-4">
<label for="legal_name">Legal Name<span class="star-red">*</span></label>
<input type="text" name="legal_name" class="form-control" required>
</div>
</div>
<!-- Row 2 -->
<div class="row mt-4">
<!-- <div class="col-md-4">
<label for="industry">Industry<span class="star-red">*</span></label>
<select name="industry" class="selectpicker">
<option value="distribution">Distribution</option>
<option value="education">Education</option>
<option value="healthcare">Healthcare</option>
<option value="manufacturing">Manufacturing</option>
<option value="retail">Retail</option>
<option value="services">Services</option>
</select>
</div> -->
<div class="col-md-6">
<label for="brn">Business Registration No.</label>
<input type="text" name="brn" class="form-control">
</div>
<div class="col-md-6">
<label for="vat">VAT Registration No.</label>
<input type="text" name="vat" class="form-control">
</div>
</div>
<!-- Row 3 -->
<h5 class="mt-4">Industry</h5>
<div class="row">
<div class="col-md-4">
<div class="form-check">
<input type="checkbox" name="industry_distribution" class="form-check-input">
<label for="industry_distribution" class="form-check-label">Distribution</label>
</div>
</div>
<div class="col-md-4">
<div class="form-check">
<input type="checkbox" name="industry_education" class="form-check-input">
<label for="industry_education" class="form-check-label">Education</label>
</div>
</div>
<div class="col-md-4">
<div class="form-check">
<input type="checkbox" name="industry_healthcare" class="form-check-input">
<label for="industry_healthcare" class="form-check-label">Healthcare</label>
</div>
</div>
</div>
<div class="row mt-2">
<div class="col-md-4">
<div class="form-check">
<input type="checkbox" name="industry_manufacturing" class="form-check-input">
<label for="industry_manufacturing" class="form-check-label">Manufacturing</label>
</div>
</div>
<div class="col-md-4">
<div class="form-check">
<input type="checkbox" name="industry_retail" class="form-check-input">
<label for="industry_retail" class="form-check-label">Retail</label>
</div>
</div>
<div class="col-md-4">
<div class="form-check">
<input type="checkbox" name="industry_services" class="form-check-input">
<label for="industry_services" class="form-check-label">Services</label>
</div>
</div>
</div>
<!-- Row 4 -->
<div class="row mt-4">
<div class="col-md-6">
<label for="effective_start_date">Effective Start Date<span class="star-red">*</span></label>
<input type="date" name="effective_start_date" class="form-control" required>
</div>
<div class="col-md-6">
<label for="effective_end_date">Effective End Date:</label>
<input type="date" name="effective_end_date" class="form-control">
</div>
</div>
<!-- Hidden Input - User -->
<input type="hidden" name="user_email" />
<div class="float-right mt-3">
<button type="submit" class="btn btn-custom save">Save and Close</button>
</div>
</div>
</form>
</div>
Any help would be greatly appreciated. If you need any additional info, let me know and I will edit the post.
I did not find any code to show the errors in html.
According to the function in views, if the form is not valid, then it renders the page with the form.
Try to add {{form.errors}} to you the html file to see if it has errors?
I managed to solve it.
views.py
#login_required
def organization_add(request):
if request.method == 'POST':
form = OrganizationAddForm(request.POST)
if form.is_valid():
form.organization_code = form.cleaned_data['organization_code']
form.company_name = form.cleaned_data['company_name']
form.legal_name = form.cleaned_data['legal_name']
form.business_registration_no = form.cleaned_data['business_registration_no']
form.vat_registration_no = form.cleaned_data['vat_registration_no']
form.industry_distribution = form.cleaned_data['industry_distribution']
form.industry_education = form.cleaned_data['industry_education']
form.industry_healthcare = form.cleaned_data['industry_healthcare']
form.industry_manufacturing = form.cleaned_data['industry_manufacturing']
form.industry_retail = form.cleaned_data['industry_retail']
form.industry_services = form.cleaned_data['industry_services']
form.effective_start_date = form.cleaned_data['effective_start_date']
form.effective_end_date = form.cleaned_data['effective_end_date']
org = form.save(commit=False)
org.created_by = request.user
org.last_updated_by = request.user
org.save()
return redirect('organizations_settings')
else:
form = OrganizationAddForm()
return render(request, 'settings/add_organization.html', {'form': form})
The issue was that it was not able to capture the user email for the Created By and Last Updated By fields.
This is resolved by using:
org = form.save(commit=False)
org.created_by = request.user
org.last_updated_by = request.user
Note that the following two posts helped me:
Using request.user with Django ModelForm
Cannot assign "42": "Event.user_id" must be a "User" instance

django comment form on post detailview

i am still learning django. trying to create a comment form in my blogdetail view.. i am following a tutorial from youtube..
https://www.youtube.com/watch?v=An4hW4TjKhE&t=40s
this tutorial has form which takes users from django users .. but in my form i want user to enter his name ,email and content..
following this tutorial i made form model but i have no idea how to get data from my own html form by this..
i have reached to a stage where in admin i can add comments and display them in my html file but now i am getting an error..
name 'post' is not defined
my files are..
forms.py
from django import forms
from.models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('content', 'email', 'name' ,)
models.py
class BlogPost(models.Model):
title = models.CharField(max_length=500)
writer = models.CharField(max_length=150,default='my dept')
category =models.CharField(max_length=150)
image = models.ImageField(upload_to='images')
post = models.TextField(max_length=2000)
Date = models.DateField( default=datetime.date.today)
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey(BlogPost , on_delete=models.CASCADE)
name = models.CharField (max_length = 150)
email = models.CharField (max_length = 150)
content = models.TextField ()
def __str__(self):
return self.email
views.py
def detailview(request, id=None):
blg = get_object_or_404(BlogPost, id=id)
comments = Comment.objects.filter( post=blg).order_by('-id')
if request.method == 'POST':
comment_form = CommentForm(request.POST or None )
if comment_form.is_valid():
content = request.POST.get('content')
Comment.objects.create(post= post , content=content)
comment_form.save()
else:
comment_form = CommentForm()
context = {'blg': blg,
'comments': comments,
'comment_form' : comment_form,
}
return render(request, 'blog/blogdetail.html', context)
blogdetail.html
<div id="respond" class="clearfix">
<div class="title-box">
<h3>Leave a <strong>Comment</strong></h3>
</div><!-- end title-box -->
<div class="row">
<!-- start Comment Form -->
<form class="clearfix" action="#" method="post" id="commentform">
{% csrf_token %}
<p class="comment-notes"><span id="email-notes">Your email address will not be published.</span> Required fields are marked <span class="required">*</span></p>
<div class="form-group">
<div class="col-sm-12">
<label>Comment<span class="required">*</span></label>
<textarea name="comment" cols="58" rows="7" tabindex="4" class="form-control" required >{{comment.content}}</textarea>
</div>
</div><!-- end form-group -->
<div class="form-group">
<div class="col-sm-6">
<label>Name<span class="required">*</span></label>
<input name="author" id="author" value="" size="22" tabindex="1" class="form-control" type="text" required >{{comment.name}}</div>
<div class="col-sm-6">
<label>Email<span class="required">*</span></label>
<input name="email" id="email" value="" size="22" tabindex="2" class="form-control" type="text" required >{{comment.email}}</div>
</div><!-- end form-group -->
<div class="form-group">
<div class="col-sm-12">
<button name="submit" type="submit" id="submit-button" tabindex="5" value="Submit" class="btn btn-shutter-out-horizontal btn-lg">Submit Comment</button>
</div>
</div><!-- end form-group -->
</form>
<!-- end Comment Form -->
</div>
</div><!-- #respond end -->
it actually looks like this
[![comment form][1]][1]
i want to post name email and comment from front end .. wasted almost 2 days without no success.. please help..
[1]: https://i.stack.imgur.com/HjDZ6.png
since you are passing the data manually from html rewrite this function
if comment_form.is_valid():
content = request.POST.get('content', '')
email = request.POST.get('email', '')
name = request.POST.get('author', '')
comment =Comment.objects.create(post= blg, email=email, name=name, content=content)
return redirect('posts-detail', pk=comment.id )<this can be how you like it>
what you are missing is getting the missing fields in html they are taken from name attribute in the input
if comment_form.is_valid():
content = request.POST.get('content')
Comment.objects.create(post= blg , content=content) # YOU HAVE ADDED post= post even post variable you are not define
comment_form.save()

Update in django

I am new to django and I want to make an update view but I can't succeed.
I have this page that shows information about a user, and when I press the 'Update My Profile' button I want to update or save(i.e if I change 'Laszlo' with 'Lucy' I want to update it and if I write in the 'nickname' input: 'NICKNAME' I want to save that infomartion into de dababase so next time when I access this page to show me all the information about the user)
My models: 'UserProfile'(which is the 'User') and 'User_Details'(they are in 1-1 relationship)
class UserProfile(AbstractUser):
pass
class User_Details(models.Model):
user = models.OneToOneField(UserProfile, on_delete=models.CASCADE)
first_name = models.CharField(max_length=50, blank = True)
last_name = models.CharField(max_length=50, blank=True)
gender = models.CharField(max_length=6, blank=True, default='')
image = models.ImageField(upload_to='avatar_image', blank=True, null=True)
public_info=models.CharField(max_length=100, blank=False, default='')
nickname=models.CharField(max_length=100,blank=True,default="")
website=models.CharField(max_length=100,blank=True,default="")
My view to show the information:
class ShowProfile(APIView):
renderer_classes = [TemplateHTMLRenderer]
template_name = 'profile.html'
def get(self, request, pk, format=None):
details = UserProfile.objects.get(id=pk)
serializer = UserProfileSerializer(details)
pprint.pprint(json.loads(JSONRenderer().render(serializer.data)))
return Response({'seri':serializer.data})
Serializers:
class UserDetailsSerializer(serializers.ModelSerializer):
class Meta:
model = User_Details
fields = (
'first_name',
'last_name',
'gender',
'public_info',
'nickname',
'website'
)
class UserProfileSerializer(serializers.ModelSerializer):
user_details = UserDetailsSerializer()
lookup_field = 'username'
class Meta:
model = UserProfile
fields = ('id', 'user_details')
Template:
{% extends 'base2.html' %}
{% load rest_framework %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-3 ">
<div class="list-group ">
Profile
My Posts
</div>
</div>
<div class="col-md-9">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-md-12">
<h4>Your Profile</h4>
<hr>
</div>
</div>
<div class="row">
<div class="col-md-12">
<form>
<div class="form-group row">
<label for="username" class="col-4 col-form-label">User Name*</label>
<div class="col-8">
<input id="username" name="username" placeholder="" class="form-control here" required="required" type="text">
</div>
</div>
<div class="form-group row">
<label for="name" class="col-4 col-form-label">First Name</label>
<div class="col-8">
<input id="name" name="first_name" placeholder= {{ seri.user_details.first_name }} class="form-control here" type="text">
</div>
</div>
<div class="form-group row">
<label for="lastname" class="col-4 col-form-label">Last Name</label>
<div class="col-8">
<input id="lastname" name="last_name" placeholder={{ seri.user_details.last_name}} class="form-control here" type="text">
</div>
</div>
<div class="form-group row">
<label for="text" class="col-4 col-form-label">Nick Name*</label>
<div class="col-8">
<input id="text" name="nickname" placeholder="{{ seri.user_details.nickname}}" class="form-control here" required="required" type="text">
</div>
</div>
<div class="form-group row">
<label for="website" class="col-4 col-form-label">Website</label>
<div class="col-8">
<input id="website" name="website" placeholder="{{seri.user_details.website}} " class="form-control here" type="text">
</div>
</div>
<div class="form-group row">
<label for="publicinfo" class="col-4 col-form-label">Public Info</label>
<div class="col-8">
<textarea id="publicinfo" name="public_info" cols="40" rows="4" class="form-control" placeholder='{{seri.user_details.public_info}}'></textarea>
</div>
</div>
<div class="form-group row">
<div class="offset-4 col-8">
<button name="submit" type="submit" class="btn btn-primary">Update My Profile</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
I tried to make this(into the 'ShowProfile' view) :
def put(self, request,pk):
serializer = ProfileUpdateSerializer()
post = request.POST.copy()
serializer.update(validated_data=dict(post))
return HttpResponseRedirect('/account/login.html')
Serializer
class ProfileUpdateSerializer(serializers.HyperlinkedModelSerializer):
first_name = serializers.CharField(source='User_Details.first_name')
last_name = serializers.CharField(source='User_Details.last_name')
gender = serializers.CharField(source='User_Details.gender')
public_info = serializers.CharField(source='User_Details.public_info')
# image=serializers.ImageField(source='User_Details.image')
nickname = serializers.CharField(source='User_Details.nickname')
website = serializers.CharField(source='User_Details.website')
class Meta:
model = User_Details
fields = ('first_name', 'last_name', 'gender', 'public_info', 'nickname', 'website')
def update(self, validated_data, uid):
user = UserProfile.objects.get(id=uid)
firstname = validated_data.pop('user_details.firstname')[0]
lastname = validated_data.pop('user_details.lastname')[0]
user.user_details.firstname = firstname
user.user_details.lastname = lastname
# if avatar:
# user.user_details.avatar = avatar
# if password != '':
# user.set_password(password)
user.user_details.save()
user.save()
return user
And in template I change the '' with this:
<form action="{% url 'show_profile' pk=user.id %}" method="PUT" enctype="multipart/form-data">
I don't know how to make to work?How can I do it?Thank you!
The problem is in <form action="{% url 'show_profile' pk=user.id %}" method="PUT" enctype="multipart/form-data">. There is no method PUT in html tag form. You have to use javascript to send such request.
P.S. it is possible to send put-like request using form, but it will look ugly and it wont be REST

I have a bound ModelForm that is invalid

I am trying to create a ModelForm that links to an external database, and when you submit the form the external database gets updated. The problem comes when I check the validity of the form, it is invalid.
I have done some researching into this and found the most common problem was that the form is not bound, but when I use print(form.non_field_errors) I get:
<bound method BaseForm.non_field_errors of <EmailForm bound=True, valid=False, fields=(subject;body;name;altsubject;utm_source;utm_content;utm_campaign)>
models.py:
class MarketingEmails(models.Model):
messageid = models.AutoField(db_column='column1', primary_key=True)
subject = models.CharField(db_column='column2', max_length=2000)
body = models.TextField(db_column='column3') #using a text field as there is no maximum length
name = models.CharField(db_column='column4', max_length=25)
altsubject = models.CharField(db_column='column5', max_length=2000)
utm_source = models.CharField(db_column='column6', max_length=25)
utm_content = models.CharField(db_column='column7', max_length=25)
utm_campaign = models.CharField(db_column='column8', max_length=25)
class Meta:
managed = False
db_table = ''
forms.py:
class EmailForm(forms.ModelForm):
class Meta:
model = MarketingEmails
fields = ['messageid','subject','body','name','altsubject','utm_source','utm_content','utm_campaign']
views.py:
def emailinfo(request, pk):
if request.session.has_key('shortname'):
shortname = request.session['shortname']
rows = get_object_or_404(MarketingEmails, pk=pk)
if request.method == 'POST':
form = EmailForm(request.POST)
print(form.errors)
print(form.non_field_errors)
if form.is_valid():
form.save()
print("form is valid")
return redirect('marketingemails:emailinfo', pk = rows.messageid)
return render(request, 'marketingemails/emailinfo.html',{'shortname': shortname, 'rows': rows})
else:
return HttpResponseRedirect(reverse('common:login'))
urls.py:
app_name = 'marketingemails'
urlpatterns = [
url(r'^marketing/emails/(?P<pk>[0-9]+)/$', marketingviews.emailinfo, name='emailinfo'),
]
html:
<form method="POST" class="post-form" action ="">
{% csrf_token %}
<label for="exampleTextarea">Name</label>
<textarea class="form-control" id="exampleTextarea" rows="1">{{ rows.name }}</textarea>
<label for="exampleTextarea">Subject</label>
<textarea class="form-control" id="exampleTextarea" rows="1">{{ rows.subject }}</textarea>
<label for="exampleTextarea">Alternative Subject</label>
<textarea class="form-control" id="exampleTextarea" rows="1">{{ rows.altsubject }}</textarea>
<label for="exampleTextarea">Body</label>
<div class="ibox-content no-padding">
<div class="summernote">
{{ rows.body }}
</div>
</div>
<label for="exampleTextarea">utm_source</label>
<textarea class="form-control" id="exampleTextarea" rows="1">{{ rows.utm_source }}</textarea>
<label for="exampleTextarea">utm_content</label>
<textarea class="form-control" id="exampleTextarea" rows="1">{{ rows.utm_content }}</textarea>
<label for="exampleTextarea">utm_campaign</label>
<textarea class="form-control" id="exampleTextarea" rows="1">{{ rows.utm_campaign }}</textarea>
<button type="submit" class="save btn btn-default">Save</button>
</form>
Your HTML form doesn't name the fields so the form can't get them. You want to use the form for rendering too : https://docs.djangoproject.com/en/1.11/topics/forms/#working-with-form-templates

Categories