My django cabin form is not submitting. I have applied foreign key and slug in my cabin's model and after that my form stopped getting submitted. whenever I enter all the fields and hit submit button,the form page is getting reloaded and no data is getting submitted.Most Importantly it is not showing any error so that I can fix it.I have tried and searched a lot about it and tried different things but still it didn't work. I am stuck to it. Please help!!
class Centre(models.Model):
name= models.CharField(max_length=50, blank=False, unique=True)
address = models.CharField(max_length =250)
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$',
message="Phone number must be entered in the format: '+999999999'. Up to 10 digits allowed.")
contact = models.CharField(max_length=100, blank=False)
phone = models.CharField(validators=[phone_regex], max_length=10, blank=True) # validators should be a list
slug = models.SlugField(unique=False)
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Centre, self).save(*args, **kwargs)
class Cabin(models.Model):
random_string = str(random.randint(100000, 999999))
centre_name = models.ForeignKey(Centre, on_delete=models.CASCADE,blank=True,null=True)
code = models.CharField(max_length=6, blank=False, unique=True, default=random_string)
total_seats = models.IntegerField(blank='False')
category=models.CharField(max_length=100, default=False)
booked_date=models.DateField(blank='False')
released_date=models.DateField(blank='False')
price=models.IntegerField(blank=False, default=None)
slug = models.SlugField(unique=False,default=None)
def save(self, *args, **kwargs):
self.slug = slugify(self.category)
super(Cabin, self).save(*args, **kwargs)
In views.py file
class CabinCreateView(CreateView):
fields = '__all__'
model = Cabin
success_url = reverse_lazy("NewApp:logindex")
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.cabin = Cabin.objects.filter(slug=self.kwargs['slug'])[0]
self.object.save()
return HttpResponseRedirect(self.get_success_url())
In my cabin template,
<div class="row">
<div class="col-md-6">
<form method="POST">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="col col-md-12">
<div class="fieldWrapper" >
{{ form.centre_name.errors }}
<div class="form-group col col-md-3">
<label>Centre Name</label>
{{form.centre_name}}
</div>
<div class="form-group col col-md-3" style="float:right; margin-top=-80px;width=200%">
<label for="{{form.code.id_for_label}" style="margin-left:200px;width:200%;white-space:nowrap;">Code</label>
<input type="text" placeholder="Code" value="{{form.code.value}}" name="code" maxlength="6" id="id_code" style="width:500px; margin-left:200px;">
</div>
</div>
<div class="col col-md-12">
<div class="form-group col col-md-3" style="float:right; margin-top=-80px;">
<label for="{{form.total_seats.id_for_label}" style="margin-left:200px;width:200px;white-space:nowrap;">seats</label>
<input type="text" placeholder="seats" name="total_seats" id="id_total_seats" style="width:500px; margin-left:200px;">
</div>
<div class="fieldWrapper" >
{{ form.category.errors }}
<div class="form-group col col-md-3" >
<label for="{{form.category.id_for_label}" style="margin-top:-40px">Category</label>
<input type="text" name="category" maxlength="100" id="id_category" placeholder="Category" style="width:500px";>
</div></div></div>
<div class="col col-md-12">
<div class="fieldWrapper" >
{{ form.released_date.errors }}
<div class="form-group col col-md-3" style="float:right; margin-top=-80px;">
<label for="{{form.released_date.id_for_label}" style="margin-left:200px;width:200px;white-space:nowrap;">released date</label>
<input type="text" placeholder="%yyyy-mm-dd" name="released_date" id="id_released_date" style="width:500px; margin-left:200px;">
</div>
</div>
<div class="fieldWrapper" >
{{ form.booked_date.errors }}
<div class="form-group col col-md-3" >
<label for="{{form.booked_date.id_for_label}" style="margin-top:-40px">booked date</label>
<input type="text" name="booked_date" id="id_booked_date" placeholder="%yyyy-mm-dd" style="width:500px";>
</div>
</div>
</div>
<div class="col col-md-12">
<div class="form-group col col-md-3" >
<label for="{{form.price.id_for_label}" style="margin-top:-40px">price</label>
<input type="text" name="price" maxlength="10" id="id_price" placeholder="in rupees" style="width:500px";>
</div>
</div>
<div class="form-group col col-md-3" >
<input type="submit" onclick="comparedate()" value="Save" class="btn btn-primary" style=" height:30px;width:80px;padding-bottom:2em;"/>
</div></div>
</form>
</div></div></div></div></div></div></div></div></div></div>
It looks like your problem is in your views.py file. You are telling the view that it should build a form including __all__ of the fields on the model, but in your template you don't include the slug field. Since you have overridden the save method on the Cabin model to populate the slug field, I guess you don't want that displayed in the template.
You have two options for fixing this. You could add a hidden field to the template containing the slug field. Or, what I think is a better option, you can change the fields attribute on your view to exclude the slug field.
class CabinCreateView(CreateView):
fields = ('centre_name', 'code', 'total_seats', 'category', 'booked_date', 'released_date', 'price',)
model = Cabin
success_url = reverse_lazy("NewApp:logindex")
P.S. This isn't a problem you are asking about, but I couldn't help noticing that you have what looks like multiple broken variables in your template. You might want to check if your label for="" attributes are working as expected.
Related
When I submitting the form in django it is giving error ''TypeError at /user expected string or bytes-like object''.
This is my staff models
class staff(models.Model):
id = models.AutoField
name = models.CharField(max_length=250)
role = models.CharField(max_length=250)
salary = models.CharField(max_length=250)
address = models.CharField(max_length=250)
number = models.CharField(max_length=250)
date = models.DateField()
This is my user views.
def user(request):
if request.method == "POST" :
name = request.POST['name']
role = request.POST['role']
salary = request.POST['salary']
address = request.POST['address']
number = request.POST['number']
date = DateTimeField()
ins = staff(name=name, role=role, salary=salary, address=address, date=date, number=number)
ins.save()
staffs = staff.objects.all()
return render(request, "salary/user.html", {'staff': staffs})
and this is form of template user.html
<form class="forms-sample" action="/user" method="post">
{% csrf_token %}
<div class="form-group row">
<label for="exampleInputUsername2" class="col-sm-3 col-form-label">Name:</label>
<div class="col-sm-9">
<input type="text" name="name" id="name" class="form-control" id="exampleInputUsername2" placeholder="Username">
</div>
</div>
<div class="form-group row">
<label for="exampleInputUsername2" class="col-sm-3 col-form-label">Role:</label>
<div class="col-sm-9">
<input type="text" name="role" id="role" class="form-control" id="exampleInputUsername2" placeholder="Role">
</div>
</div>
<div class="form-group row">
<label for="exampleInputUsername2" class="col-sm-3 col-form-label">Salary:</label>
<div class="col-sm-9">
<input type="text" name="salary" id="salary" class="form-control" id="exampleInputUsername2" placeholder="Salary">
</div>
</div>
<div class="form-group row">
<label for="exampleInputUsername2" class="col-sm-3 col-form-label">Address:</label>
<div class="col-sm-9">
<input type="text" name="address" id="address" class="form-control" id="exampleInputUsername2" placeholder="Address">
</div>
</div>
<div class="form-group row">
<label for="exampleInputUsername2" class="col-sm-3 col-form-label">Mobile no.:</label>
<div class="col-sm-9">
<input type="text" name="number" id="number" class="form-control" id="exampleInputUsername2" placeholder="Mobile no.">
</div>
</div>
<button type="submit" class="btn btn-primary mr-2">Submit</button>
<button class="btn btn-dark">Cancel</button>
</form>
I am new in django and i not know what the problem is.
Thanks for helping in advance.
It makes no sense to pass a reference to the AutoField model field in your model, you should construct a field, so:
class staff(models.Model):
id = models.AutoField()
# ⋮
as for the date field, you can work with auto_now_add=True [Django-doc] to automatically fill in the current day:
class staff(models.Model):
# ⋮
date = models.DateField(auto_now_add=True)
then this can be omitted while constructing a staff object:
def user(request):
if request.method == "POST" :
name = request.POST['name']
role = request.POST['role']
salary = request.POST['salary']
address = request.POST['address']
number = request.POST['number']
# no date=… ↓
ins = staff.objects.create(name=name, role=role, salary=salary, address=address, number=number)
ins.save()
staffs = staff.objects.all()
return render(request, "salary/user.html", {'staff': staffs})
It might however be better to work with Django forms to validate, clean and fill in data from a POST request.
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.
Note: Models in Django are written in PascalCase, not snake_case,
so you might want to rename the model from staff to Staff.
how can i save many courses to the student table .I want to keep my design like this.This code is not saving the many to many field(courses) through AddStudentForm.It returns an error with courses variable.If i used CharField instead of ManyToManyField in models for courses then the code works perfectly,but when i use ManyToManyField then it is not working.
it throws courses when i used form.errors .If i didn't use form.errors then it doesn't give any error neither saves the data.
how can i save many courses to the student table .I want to keep my design like this.This code is not saving the many to many field(courses) through AddStudentForm.It returns an error with courses variable.
models.py
class Course(models.Model):
title = models.CharField(max_length=250)
price = models.IntegerField(default=0)
duration = models.CharField(max_length=50)
def __str__(self):
return self.title
class Student(models.Model):
name = models.CharField(max_length=100)
courses = models.ManyToManyField(Course)
email = models.EmailField()
image = models.ImageField(upload_to='Students',blank=True)
def __str__(self):
return self.name
forms.py
class AddStudentForm(forms.ModelForm):
# courses = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Course.objects.all())
class Meta:
model = Student
fields = ['name','courses','email','image']
def __init__(self, *args, **kwargs):
super(AddStudentForm, self).__init__(*args, **kwargs)
self.fields["courses"].widget = CheckboxSelectMultiple()
self.fields["courses"].queryset = Course.objects.all()
views.py
def addstudent(request):
courses = Course.objects.all()
if request.method == 'POST':
form = AddStudentForm(request.POST,request.FILES)
if form.is_valid():
student = form.save(commit=False)
course = form.cleaned_data['courses']
student.courses = course
student.save()
# student.courses.add(course)
# student.save_m2m()
# student.courses.set(course) # this method also didn't helped me
messages.success(request, 'student with name {} added.'.format(student.name))
return redirect('students:add_student')
else:
# messages.error(request,'Error in form.Try again')
return HttpResponse(form.errors) # this block is called and returns courses
else:
form = AddStudentForm()
return render(request,'students/add_student.html',{'form':form,'courses':courses})
add_student.html
<form action="{% url 'students:add_student' %}"
method="post"
enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<h5>Full Name <span class="text-danger">*</span>
</h5>
<div class="controls">
<input type="text" name="name" class="form-
control" > </div>
</div>
<div class="form-group">
<h5>Courses<span class="text-danger">*</span>
</h5>
<div class="controls">
{% for course in courses %}
<input name ="courses" type="checkbox" id="course-
{{course.id}}" value="{{course.title}}">
<label for="course-{{course.id}}">{{course.title}}
</label>
{% endfor %} # i think the problem is here.
</div>
</div>
<div class="form-group">
<h5>Email <span class="text-danger">*</span></h5>
<div class="controls">
<input type="text" name="email" class="form-
control" required> </div>
</div>
</div>
<div class="form-group">
<h5>Image <span class="text-danger">*</span></h5>
<div class="controls">
<input type="file" name="image" class="form-control" > </div>
</div>
<div class="text-xs-right">
<button type="submit" class="btn btn-info">Add</button>
</div>
</form>
You need to save first before you can assign m2m, the system needs the primary key of the Student model before it can insert into the m2m table.
if form.is_valid():
student = form.save(commit=False)
course = form.cleaned_data['courses']
student.save()
# this will save by itself
student.courses.set(course)
I have a booking system in which i enter dates and timeslots available to book.
the form gets the timeslots from the date and converts it to the user timezone time.
i want the client to select a date and an available timeslot before continuing the form but even with required it doesnt work.
i have a model for timeslots and one for event, date+timeslot
then a form to make client select available date+timeslot, with a html to find timeslot available for each day
html
<option value="">{% if time_slots %}Available Slots{% else %}No Slot Available{% endif %}</option>
{% for time_set in time_slots %}
<option value="{{ time_set.pk }}">{{ time_set.start }} - {{ time_set.end }}</option>
{% endfor %}
models
class TimeSlots(models.Model):
start = models.TimeField(null=True, blank=True)
end = models.TimeField(null=True, blank=True)
class Meta:
ordering = ['start']
def __str__(self):
return '%s - %s' % (self.start.strftime("%I:%M %p"), self.end.strftime("%I:%M %p"))
class Event(models.Model):
event_date = models.DateField()
start = models.ForeignKey(TimeSlots, on_delete=models.CASCADE, verbose_name='Slot Time', null=True)
available = models.BooleanField(default=True)
class Meta:
verbose_name = u'Event'
verbose_name_plural = u'Event'
def __str__(self):
return str(self.event_date)
def get_absolute_url(self):
url = reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name), args=[self.pk])
return u'%s' % (url, str(self.start))
form
class PatientForm(forms.ModelForm):
class Meta:
model = Patient
fields = ('patient_name', 'patient_country','phone_number', 'email', 'event_date','start', 'timestamp', 'datestamp')
widgets = {
'event_date': DateInput(),
'patient_country': CountrySelectWidget(),
}
def __init__(self, *args, **kwargs):
super(PatientForm, self).__init__(*args, **kwargs)
self.fields['start'].queryset = TimeSlots.objects.none()
if 'event_date' in self.data:
try:
event_id = self.data.get('event_date')
# event = Event.objects.get(pk=event_id)
self.fields['start'].queryset = TimeSlots.objects.filter(event__event_date=event_id, event__available=True)
except (ValueError, TypeError):
pass # invalid input from the client; ignore and fallback to empty City queryset
elif self.instance.pk:
self.fields['start'].queryset = self.instance.timeslot_set
views
class PatientCreate(CreateView):#was CreateView
form_class = PatientForm
template_name = 'appointment/index.html'
def get_context_data(self, **kwargs): # new
context = super(PatientCreate, self).get_context_data(**kwargs)
context['key'] = settings.STRIPE_PUBLISHABLE_KEY
return context
def load_time_slots(request):
event_date = request.GET.get('event_date')
client_timezone = request.GET.get('timezone')
client_timezone = pytz.timezone(client_timezone)
event_date, original_date = get_original_event_date_by_timezone(client_timezone, event_date)
time_slots = TimeSlots.objects.filter(event__event_date= event_date, event__available=True)
final_time_slots = []
for time_slot in time_slots:
start_time = time_slot.start
original_start_date_time = original_date.replace(hour=start_time.hour, minute=start_time.minute,
second=start_time.second,
tzinfo=original_time_zone)
timezone_start_date_time = original_start_date_time.astimezone(client_timezone)
end_time = time_slot.end
original_end_date_time = original_date.replace(hour=end_time.hour, minute=end_time.minute,
second=end_time.second,
tzinfo=original_time_zone)
timezone_end_date_time = original_end_date_time.astimezone(client_timezone)
final_time_slots.append({'pk': time_slot.pk, 'start': timezone_start_date_time.time,
'end': timezone_end_date_time.time})
return render(request, 'appointment/dropdown_list_options.html', {'time_slots': final_time_slots})
def get_original_event_date_by_timezone(client_timezone, event_date):
client_date = datetime.datetime.strptime(event_date, '%Y-%m-%d')
client_date = client_date.replace(tzinfo=client_timezone)
original_date = client_date.astimezone(original_time_zone)
original_date = original_date.replace(hour=0, minute=0, second=0, microsecond=0)
event_date = original_date.strftime('%Y-%m-%d')
return event_date, original_date
def create_event(request, start_time, day_date):
time_slot = TimeSlots.objects.get(start=start_time)
Event.objects.create(event_date=day_date, start=time_slot)
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
form page html
<div class="container" style="margin-top:50px;margin-bottom:50px;">
<div class="stepwizard col-md-offset-3">
<div class="stepwizard-row setup-panel">
<div class="stepwizard-step">
1
<p>Date & Time</p>
</div>
<div class="stepwizard-step">
2
<p>Information</p>
</div>
<div class="stepwizard-step">
3
<p>Calling Method</p>
</div>
<div class="stepwizard-step">
4
<p>Payment Method</p>
</div>
</div>
</div>
<form role="form" action="{% url 'charge' %}" method="POST" id="patientForm" data-times-url="{% url 'ajax_load_time_slots' %}">
<div class="row setup-content" id="step-1">
<div class="col-xs-6 col-md-offset-3">
<div class="col-md-12">
<h3> Appointments date and time</h3>
<div class="form-group">
<label class="control-label" for="id_event_date">Event Date:</label>
<input class="form-control" type="date" name="event_date" id="id_event_date" required="required" />
</div>
<div class="form-group">
<label class="control-label" for="id_start">{% trans "Time:"%}</label>
<p><select required="required" class="form-control" name="start" style="display:inline;" id="id_start">
<option value="">---------</option></select></p><input type="hidden" name="timezone">
<script>$("#patientForm input[name='timezone']").val(Intl.DateTimeFormat().resolvedOptions().timeZone);</script>
</select></p>
</div>
<button class="btn btn-primary nextBtn btn-lg pull-right" type="button">Next</button>
</div>
</div>
</div>
<div class="row setup-content" id="step-2">
<div class="col-xs-6 col-md-offset-3">
<div class="col-md-12">
<h3> Step 2</h3>
<div class="form-group">
<label for="id_patient_fname" class="control-label">First Name:</label>
<input name="patient_name" id="id_patient_name" required="required" maxlength="100" type="text" class="form-control" placeholder="Enter First Name" />
</div>
<div class="form-group">
<label class="control-label">Last Name:</label>
<input required="required" maxlength="100" type="text" class="form-control" placeholder="Enter Last Name" />
</div>
<div class="form-group">
<label for="id_phone_number" class="control-label">Phone Number:</label>
<input name="phone_number" id="id_phone_number" required="required" maxlength="100" type="text" class="form-control" placeholder="Enter Phone Number" />
</div>
<div class="form-group">
<label for="id_emal" class="control-label">Email:</label>
<input name="email" id="id_email" maxlength="100" type="text" required="required" class="form-control" placeholder="Enter Email" />
</div>
<div class="form-group">
<label class="control-label">City</label>
<textarea required="required" class="form-control" placeholder="Enter your address"></textarea>
</div>
<button class="btn btn-primary nextBtn btn-lg pull-right" type="button">Next</button>
</div>
</div>
</div>
<div class="row setup-content" id="step-3">
<div class="col-xs-6 col-md-offset-3">
<div class="col-md-12">
<div class="form-group">
<label class="control-label">Choose The Way You Want to Receive The Video Call:</label>
<label class="radio-inline"><input class="form-control" type="radio" name="optradio" checked>Skype</label>
<label class="radio-inline"><input class="form-control" type="radio" name="optradio">Whatsapp</label>
</div>
<button class="btn btn-primary nextBtn btn-lg pull-right" type="button">Next</button>
</div>
</div>
</div>
<div class="row setup-content" id="step-4">
<div class="col-xs-6 col-md-offset-3">
<div class="col-md-12">
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button" data-key="pk_test_KPSQTmUOl1DLP2eMc7zlvcnS"
data-description="Buying a 30mn Skype Session" data-amount="3000" data-locale="auto"></script>
</div>
</div>
</div>
</form>
</div>
in the html of the form page, i add required to select but it doesnt work
i need client to select lets say 29/01/2019, then if there is availability choose a timeslote lets say 5.30pm-6.00pm, and then only the next arrow will appear
With CreateView it's a little bit tricky when you want to initialize your ModelForm data. So, instead of doing initialization under your ModelForm, do it under the CreateView class like this example:
Your form:
class PatientForm(forms.ModelForm):
class Meta:
model = Patient
fields = ('patient_name', 'patient_country','phone_number', 'email', 'event_date','start', 'timestamp', 'datestamp')
widgets = {
'event_date': DateInput(),
'patient_country': CountrySelectWidget(),
}
Your view:
class PatientCreate(CreateView):
form_class = PatientForm
template_name = 'appointment/index.html'
initial = {}
def get_initial(self):
base_initial = super().get_initial() # it's a simple dict
# initialize your form's data here
# Your logic ...
return base_initial
# The rest of your logic
...
And, in order to know why you need to do this. CreateView inherits from FormMixin which has initial and get_initial() thus will initialize your form's data instead of doing it under your form.
See this links for more details: CreateView MRO and FormMixin
I created a custom registration form:
class MyRegistrationForm(UserCreationForm):
mobile = models.CharField(max_length=16)
address = models.CharField(max_length=100)
class Meta():
model = CustomUser
fields = ['username', 'password1', 'password2', 'first_name', 'last_name', 'email', 'mobile', 'address']
def clean_mobile(self):
mobile = self.cleaned_data['mobile']
if CustomUser.objects.filter(mobile=mobile).exists():
raise ValidationError('Mobile already exists')
return mobile
def save(self, commit=True):
user = super(MyRegistrationForm, self).save(commit=False)
user.mobile = self.cleaned_data['mobile']
user.address = self.cleaned_data['address']
if commit:
user.save()
return user
And in my template, I don't write just `{{form}}', instead I use my bootstrap template for registration. It looks like:
<form class="form-horizontal" action="{% url 'register' %}" method="post">
{% csrf_token %}
<div class="control-group">
<label class="control-label" for="username1" >Ім'я користувача <sup>*</sup></label>
<div class="controls">
<input type="text" id="username1" placeholder="Нік" name="username">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password_1" >Пароль <sup>*</sup></label>
<div class="controls">
<input type="password" id="password_1" placeholder="Введіть пароль" name="password1">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password_2" >Повторіть пароль <sup>*</sup></label>
<div class="controls">
<input type="password" id="password_2" placeholder="Повторіть пароль" name="password2">
</div>
</div>
But when clean_mobile method is called and raise ValidationError, no errors aren't showed. How to solve this issue? Or maybe I can use in template {{form}} but I need to use bootstrap css?
You need to include {{ form.mobile.errors }} to display errors for your mobile field.
See the working with form templates docs for more information.
You might want to investigate django crispy forms, which makes it easy to render bootstrap forms.
I run into problems while setting up a user profile for our application. Imagine a linkedIn-like user profile with basic information, work- and education positions.
the model (simplified)
class UserProfile(models.Model):
about_me = models.TextField(blank=True, null=True)
formatted_name = models.CharField(max_length=120, null=True, blank=True)
username_slug = models.SlugField(null=True, blank=True, unique=True)
location_name = models.CharField(max_length=120, null=True, blank=True)
...
class JobPosition(models.Model):
user_profile = models.ForeignKey(UserProfile)
company_name = models.CharField(max_length=150, null=True, blank=True)
title = models.CharField(max_length=150, null=True, blank=True)
job_description = models.CharField(max_length=1000, null=True, blank=True)
start_date = models.DateField(blank=True, null=True)
end_date = models.DateField(blank=True, null=True)
class Education(models.Model):
user_profile= models.ForeignKey(UserProfile)
degree = models.CharField(max_length=60, null=True, blank=True)
field_of_study = models.CharField(max_length=120, null=True, blank=True)
school_name = models.CharField(max_length=150, null=True, blank=True)
start_date = models.DateField(blank=True, null=True)
end_date = models.DateField(blank=True, null=True)
Ok so obviously a user can have 0-n work positions ans 0-n education positions.
forms.py
class BasicForm(ModelForm):
class Meta:
model = UserProfile
fields = ['id', 'about_me', 'linkedin_headline', 'location_name']
# enter code here
class EducationForm(ModelForm):
class Meta:
model = Education
fields = ['id', 'degree', 'field_of_study', 'school_name',
'start_date','end_date']
class WorkForm(ModelForm):
class Meta:
model = JobPosition
fields = ['id','company_name', 'title', 'job_description',
'start_date','end_date']
views.py
- I wanted to have everything in one function as I want to call no other URL. (see later in template). The user should be able to edit his positions on the site, click 'update' and get redirected back on the profile site.
- I tried applying the apporach of distinguishing the post income via the name of the update button as seen here: How can I build multiple submit buttons django form?
- it's currently not doing a lot of validation stuff
def detail(request, slug):
u = get_object_or_404(UserProfile, username_slug=slug)
#checking the request on Post
if request.method == 'POST':
# Battery of IF statements to determine which form has been used
# if it's updating basic info
if 'updateBasic' in request.POST:
form = BasicForm(request.POST)
if form.is_valid():
form.save()
# if its a Work Position
if 'updateWork' in request.POST:
form = WorkForm(request.POST)
if form.is_valid():
form.save()
# ... same for education...
# if there is no POST request, then the profile is just called to be displayed
else:
basicForm = BasicForm()
educForm = EducationForm()
workForm = WorkForm()
#CSRF Token generation
c = {'user': u,
'years' : range( datetime.now().year, 1980, -1),
'months' : range( 1,13),
'basicForm': basicForm,
'educForm': educForm,
'workForm': workForm}
#CSRF Token generation
c.update(csrf(request))
return render(request, 'userprofile/detail.html', c)
The template:
Pretty straight forward. Looping over the work and education positions:
{% for work in user.positions %}
<div id="work{{ forloop.counter }}" class="row">
<div class="large-2 small-3 columns">
<h6> {{ work.end_date|date:'M Y'|default:"NOW" }}<br>{{ work.start_date|date:'M Y' }}</h6>
</div>
<div class="large-10 small-9 columns">
<h6>{{ work.title }}
<a class="show_hide editIcon" href="#" rel="#editWork{{ forloop.counter }} #work{{ forloop.counter }}" title="Edit"><i class="icon-edit pull-right editIcon icon-large"></i></a>
</h6>
<h6 class="dblue ">{{ work.company_name }}</h6>
{% if work.job_description %}
<p> {{ work.job_description}} </p>
{% endif %}
{% if not forloop.last %}
<hr>
{% endif %}
</div>
</div>
<div id="editWork{{ forloop.counter }}" style="display: none;" class="row editForm">
<div class="large-10 large-centered columns">
<h5>Edit</h5>
<form class="custom" action="#" method="post" name="WorkForm"> {% csrf_token %}
<div class="row">
<div class="large-6 columns">
<label for="company">Company:</label>
<input type="text" name="company" id="company" placeholder="Example Ltd" required value="{{ work.company_name }}"/>
</div>
<div class="large-6 columns">
<label for="title">Title:</label>
<input type="text" name="title" id="title" placeholder="Example position" required value="{{ work.title }}"/>
</div>
</div>
...
<div class="row">
<div class="large-12 columns">
<label for="desc">Description</label>
<textarea name="desc" id="desc" cols="40" rows="6" value="{{ edu.field_of_study_description }}"></textarea>
</div>
</div>
<div class="row">
<div class="large-2 small-3 columns">
<button class="tiny submit" type="submit" name="updateWork" title="Update this position" >update</button>
</div>
<div class="large-2 small-3 columns">
<button class="tiny submit" type="reset" title"Clear the form">Reset</button>
</div>
<div class="large-2 small-3 columns">
<a class="show_hide button tiny" href="#" rel="#editWork{{ forloop.counter }} #work{{ forloop.counter }}" title="Close the edit panel">Cancel</a>
</div>
<div class="large-3 columns">
<a class="button tiny secondary" href="#" title="Delete this position"> Delete</a>
</div>
</div>
</form>
</div>
</div>
{% endfor %}
So what I do:
I loop over all work positions and generate a div for editing this
exact position.
the div is shown when clicking on a 'edit Button' and javascript
kicks in to make the div visible (slides over the non-edit div)
The user should then be able to edit this exact position. click update and I call the detail action to handle the update request. (not yet implemented)
I do the same for education
I know the forms are not integrated yet. As I really have no idea how to do this in a proper way...
Questions
How can I properly display one of my modelforms for each position? (Formests are not really what I think I should use as they only allow a battery of forms rather then single instances)
how can I fill it with the corresponding value? (can that even be done at runtime or do I habe to make an array of forms filled with the values already in the view and then pass this array to the template?)
Am I in general on the right path? :)
Sorry for the lengthy post but I thought id rather give you as much info as possible so you can hopefully direct me the right way.
Already now lots of thanks in advance
Phil