Upon submission form is not validated - flask

I am trying to implement a form that collects data on a concert venue and stores it on my local postgres database using wtforms and flask-sqlalchemy orm.
I have noticed that my form fails to validate preventing me from adding the new record to my database. Please see the relevant code below
Form model
class VenueForm(FlaskForm):
name = StringField(
'name', validators=[DataRequired()]
)
city = StringField(
'city', validators=[DataRequired()]
)
state = SelectField(
'state', validators=[DataRequired()],
choices=[
('AL', 'AL'),
('AK', 'AK'),
('AZ', 'AZ'),
('AR', 'AR'),
('CA', 'CA'),
('CO', 'CO'),
('CT', 'CT'),
('DE', 'DE'),
('DC', 'DC'),
('FL', 'FL'),
('GA', 'GA'),
('HI', 'HI'),
('ID', 'ID'),
('IL', 'IL'),
('IN', 'IN'),
('IA', 'IA'),
('KS', 'KS'),
('KY', 'KY'),
('LA', 'LA'),
('ME', 'ME'),
('MT', 'MT'),
('NE', 'NE'),
('NV', 'NV'),
('NH', 'NH'),
('NJ', 'NJ'),
('NM', 'NM'),
('NY', 'NY'),
('NC', 'NC'),
('ND', 'ND'),
('OH', 'OH'),
('OK', 'OK'),
('OR', 'OR'),
('MD', 'MD'),
('MA', 'MA'),
('MI', 'MI'),
('MN', 'MN'),
('MS', 'MS'),
('MO', 'MO'),
('PA', 'PA'),
('RI', 'RI'),
('SC', 'SC'),
('SD', 'SD'),
('TN', 'TN'),
('TX', 'TX'),
('UT', 'UT'),
('VT', 'VT'),
('VA', 'VA'),
('WA', 'WA'),
('WV', 'WV'),
('WI', 'WI'),
('WY', 'WY'),
]
)
address = StringField(
'address', validators=[DataRequired()]
)
phone = StringField(
'phone'
)
image_link = StringField(
'image_link'
)
genres = SelectMultipleField(
# TODO implement enum restriction
'genres', validators=[DataRequired()],
choices=[
('Alternative', 'Alternative'),
('Blues', 'Blues'),
('Classical', 'Classical'),
('Country', 'Country'),
('Electronic', 'Electronic'),
('Folk', 'Folk'),
('Funk', 'Funk'),
('Hip-Hop', 'Hip-Hop'),
('Heavy Metal', 'Heavy Metal'),
('Instrumental', 'Instrumental'),
('Jazz', 'Jazz'),
('Musical Theatre', 'Musical Theatre'),
('Pop', 'Pop'),
('Punk', 'Punk'),
('R&B', 'R&B'),
('Reggae', 'Reggae'),
('Rock n Roll', 'Rock n Roll'),
('Soul', 'Soul'),
('Other', 'Other'),
]
)
facebook_link = StringField(
'facebook_link', validators=[URL()]
)
website_link = StringField(
'website_link'
)
seeking_talent = BooleanField( 'seeking_talent' )
seeking_description = StringField(
'seeking_description'
)
Controller
#app.route('/venues/create', methods=['POST'])
def create_venue_submission():
newForm = VenueForm()
if newForm.validate_on_submit():
venue = Venue(
name = newForm.name.data,
city = newForm.city.data,
state = newForm.state.data,
address =newForm.address.data,
phone = newForm.phone.data,
image_link =newForm.image_link.data,
genres = newForm.genres.data,
facebook_link = newForm.facebook_link.data,
seeking_description = newForm.seeking_description.data,
seeking_talent = newForm.seeking_talent.data,
website = newForm.website_link.data
)
db.session.add(venue)
db.session.commit()
flash('The Venue ' + newForm.name.data + ' has successfully been listed')
else:
db.session.rollback()
flash('An error occurred. Venue ' + newForm.name.data + ' could not be listed.')
db.session.close()
return render_template('pages/home.html')
html
<form method="post" id="venForm" class="form" action="/venues/create">
{{ form.csrf_token }}
{% if form.csrf_token.errors %}
<div class="warning">You have submitted an invalid CSRF token</div>
{% endif %}
<h3 class="form-heading">List a new venue <i class="fa fa-home pull-right"></i></h3>
<div class="form-group">
<label for="name">Name</label>
{{ form.name(class_ = 'form-control', autofocus = true) }}
</div>
<div class="form-group">
<label>City & State</label>
<div class="form-inline">
<div class="form-group">
{{ form.city(class_ = 'form-control', placeholder='City', autofocus = true) }}
</div>
<div class="form-group">
{{ form.state(class_ = 'form-control', placeholder='State', autofocus = true) }}
</div>
</div>
</div>
<div class="form-group">
<label for="address">Address</label>
{{ form.address(class_ = 'form-control', autofocus = true) }}
</div>
<div class="form-group">
<label for="phone">Phone</label>
{{ form.phone(class_ = 'form-control', placeholder='xxx-xxx-xxxx', autofocus = true) }}
</div>
<div class="form-group">
<label for="genres">Genres</label>
<small>Ctrl+Click to select multiple</small>
{{ form.genres(class_ = 'form-control', placeholder='Genres, separated by commas', autofocus = true) }}
</div>
<div class="form-group">
<label for="facebook_link">Facebook Link</label>
{{ form.facebook_link(class_ = 'form-control', placeholder='http://', autofocus = true) }}
</div>
<div class="form-group">
<label for="image_link">Image Link</label>
{{ form.image_link(class_ = 'form-control', placeholder='http://', autofocus = true) }}
</div>
<div class="form-group">
<label for="website_link">Website Link</label>
{{ form.website_link(class_ = 'form-control', placeholder='http://', autofocus = true) }}
</div>
<div class="form-group">
<label for="seeking_talent">Looking for Talent</label>
{{ form.seeking_talent(placeholder='Venue', autofocus = true) }}
</div>
<div class="form-group">
<label for="seeking_description">Seeking Description</label>
{{ form.seeking_description(class_ = 'form-control', placeholder='Description', autofocus = true) }}
</div>
<input type="submit" value="Create Venue" class="btn btn-primary btn-lg btn-block">
</form>
Whenever I try to create a venue the if newForm.validate_on_Submit() is not fulfilled and the else is executed

try passing request.form into form init
newForm = VenueForm(**request.form)

Related

How do I add reset button for crispy filter.form in Django to reset current selection in filter fields?

I have django-filters fields above django-table2 and I would like to add reset button which would clear values selected in particular filter fields.
My code:
filters.py
class DiaryFilter(django_filters.FilterSet):
def trade_win_loss(self, queryset, name, value):
if (value == 'Win'):
return queryset.filter(netpnl__gt=0)
if (value == 'Loss'):
return queryset.filter(netpnl__lt=0)
if (value == 'BE'):
return queryset.filter(netpnl=0)
return queryset
class Meta:
model = Diary
fields = ("ticker", "strategy", "position", "entryDate", "netpnl")
WIN_LOSS_CHOICES = (
('Win', 'Win'),
('Loss', 'Loss'),
('BE', 'Break Even'),
)
ticker = django_filters.CharFilter(label="Ticker", lookup_expr='icontains')
entryDate = django_filters.DateFilter(widget=DateInput(attrs={'type': 'date'}))
netpnl = django_filters.ChoiceFilter(empty_label='---------', label="NetP/L", choices=WIN_LOSS_CHOICES, method="trade_win_loss")
class DiaryFilterFormHelper(FormHelper):
form_method = 'GET'
layout = Layout(
Div(
Div("ticker", css_class="col-6 col-sm-4 col-md-2"),
Div("strategy", css_class="col-6 col-sm-4 col-md-2"),
Div("position", css_class="col-6 col-sm-4 col-md-2"),
Div("entryDate", css_class="col-6 col-sm-4 col-md-3 col-lg-2"),
Div("netpnl", css_class="col-6 col-sm-4 col-md-2"),
Div(Submit('submit', 'Filter', css_class='btn btn-dark'), css_class="col-2 col-md-2 col-lg-1 block my-auto align-bottom"),
Div(Submit('reset', 'Clear', css_class='btn btn-dark'), css_class="col-1 block my-auto align-bottom"),
css_class="row"
)
)
views.py
class DiaryView(LoginRequiredMixin, SingleTableMixin, FilterView):
template_name = "diary.html"
model = Diary
table_class = DiaryTable
filterset_class = DiaryFilter
table_pagination = {
"per_page": 10
}
def get_filterset(self, filterset_class):
filterset = super().get_filterset(filterset_class)
filterset.form.helper = DiaryFilterFormHelper()
return filterset
html template
<div class="col-11">
<div class="text-center justify-content-center align-bottom">
{% crispy filter.form %}
</div>
{% render_table table %}
</div>
As I am beginner, I was searching for a similar code, but did not find anything useful. I expect that I should probably write some function and assign it somehow to the Clear button in filters.py, so any help with example of code would be appreciated.

formset function update view does not save the forms because the id is missing

I have a view to update 6 of my formset only that the click of the send button gives me the error that the id of each form is missing ... how do you fix it?
When I have to create formset there are never problems with the id...
Can anyone tell me where I'm wrong? I leave my code below
view
#login_required
def PianoSingleUpdateView(request, id):
piano = models.Piano.objects.get(single_piano__id = id)
piano_sett = models.PianoSingleDay.objects.get(id = id)
dato = models.PianoDay.objects.filter( piano_day = piano_sett)
DatiFormSet = modelformset_factory(models.PianoDay, extra = 0, fields=('id', 'kcal', 'carboidrati', 'proteine', 'grassi'))
if request.method == 'POST':
dati_formset = DatiFormSet(request.POST, request.FILES, queryset = dato)
if dati_formset.is_valid():
for dato in dati_formset:
dato.save()
return redirect('gestione-piano', id = piano.id)
else:
dati_formset = DatiFormSet(queryset = dato)
context = {'piano': piano, 'piano_sett': piano_sett, 'dati_formset': dati_formset}
return render(request, 'crud/update/update_piano_giornaliero.html', context)
models
class Piano(models.Model):
nome_piano = models.CharField(max_length=100)
data_inizio = models.DateField()
data_fine = models.DateField()
utente_piano = models.ForeignKey(
User,
on_delete = models.CASCADE,
related_name = 'utente_piano'
)
def __str__(self):
return self.nome_piano
class PianoSingleDay(models.Model):
giorni_settimana_scelta = [
("1","Lunedì"),
("2","Martedì"),
("3","Mercoledì"),
("4","Giovedì"),
("5","Venerdì"),
("6","Sabato"),
("7","Domenica")
]
giorni_settimana = models.CharField(
choices = giorni_settimana_scelta,
max_length = 300
)
single_piano = models.ForeignKey(
Piano,
on_delete = models.CASCADE,
related_name = 'single_piano'
)
def __str__(self):
return self.giorni_settimana
class PianoDay(models.Model):
scelta_pasto = [
("1","Colazione"),
("2","Spuntino mattina"),
("3","Pranzo"),
("4","Merenda"),
("5","Cena"),
("6","Spuntino sera")
]
pasto = models.CharField(
choices = scelta_pasto,
max_length = 300,
default = '-'
)
kcal = models.IntegerField(default = 0)
grassi = models.IntegerField(default = 0)
carboidrati = models.IntegerField(default = 0)
proteine = models.IntegerField(default = 0)
piano_day = models.ForeignKey(
PianoSingleDay,
on_delete = models.CASCADE,
related_name = 'piano_day'
)
file html
<form method="post" novalidate autocomplete="off" class="form-not-box">
{% csrf_token %}
<div class="box-schede">
<div class="alert alert-pop-up mt-3" role="alert">
Le colonne lasciate a 0 non verranno considerate.
</div>
{{ dati_formset.management_form }}
<div class="row mt-3">
{% for dati in dati_formset %}
<div class="col-lg-2">
<div class="info-piano">
<div class="ico">
{% if forloop.counter == 1 %}
<object type="image/svg+xml" data="{% static 'img/icone/colazione.svg' %}">
Icona colazione
</object>
{% elif forloop.counter == 3 %}
<object type="image/svg+xml" data="{% static 'img/icone/pranzo.svg' %}">
Icona pranzo
</object>
{% elif forloop.counter == 5 %}
<object type="image/svg+xml" data="{% static 'img/icone/cena.svg' %}">
Icona cena
</object>
{% elif forloop.counter == 2 or forloop.counter == 4 or forloop.counter == 6 %}
<object type="image/svg+xml" data="{% static 'img/icone/merenda.svg' %}">
Icona cena
</object>
{% endif %}
</div>
<div class="form-floating mb-3 mt-3">
{{ dati.kcal|add_class:'form-control'|append_attr:"placeholder: dati" }}
{{ dati.kcal.label_tag }}
</div>
<div class="form-floating mb-3">
{{ dati.carboidrati|add_class:'form-control'|append_attr:"placeholder: dati" }}
{{ dati.carboidrati.label_tag }}
</div>
<div class="form-floating mb-3">
{{ dati.proteine|add_class:'form-control'|append_attr:"placeholder: dati" }}
{{ dati.proteine.label_tag }}
</div>
<div class="form-floating">
{{ dati.grassi|add_class:'form-control'|append_attr:"placeholder: dati" }}
{{ dati.grassi.label_tag }}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="buttons mb-3">
Indietro
<input type="submit" class="btn btn-warning" value="Aggiorna piano">
</div>
</form>
My observation tells me that your problem is the DatiFormSet fields which shouldn't contain id value and also your function view had in queryset = dato which is not needed, but in some cases you should add an instance of Piano.
#login_required
def PianoSingleUpdateView(request, id):
piano = models.Piano.objects.get(single_piano__id = id)
piano_sett = models.PianoSingleDay.objects.get(id = id)
dato = models.PianoDay.objects.filter( piano_day = piano_sett)
DatiFormSet = modelformset_factory(models.PianoDay, extra = 0, fields=('kcal', 'carboidrati', 'proteine', 'grassi'))
if request.method == 'POST':
dati_formset = DatiFormSet(request.POST, request.FILES , instance=piano)
if dati_formset.is_valid():
for dato in dati_formset:
dato.save()
return redirect('gestione-piano', id = piano.id)
else:
dati_formset = DatiFormSet(request.POST)
context = {'piano': piano, 'piano_sett': piano_sett, 'dati_formset': dati_formset}
return render(request, 'crud/update/update_piano_giornaliero.html', context)

Django nested forms

I have trouble figuring out how to create nested forms. I have two models: Poll and Question (foreign key for Poll is inside Question model). I want it to be possible to add several questions for the poll dynamically inside one form. I've already tried making it work with inlineform_factory, but found troubles saving the form. Right now I have overcomplicated code that throws MultiValueDictError after saving the poll for the second time. I thought maybe there is some other way. Here's my code
models.py
class Question(models.Model):
type_choices = (
('text', 'Текстовый'),
('integer', 'Числовой'),
)
type = models.CharField(verbose_name=u'Тип вопроса', choices=type_choices, max_length=70)
text = models.CharField(verbose_name=u'Текст вопроса', max_length=255)
poll = models.ForeignKey('Poll', on_delete=models.CASCADE, related_name='questions')
class Poll(BaseFields):
objects = models.Manager()
published = PublishedManager()
title = models.CharField(verbose_name=u'Заголовок', max_length=70)
date_from = models.DateTimeField(u'Дата начала')
date_to = models.DateTimeField(u'Дата окончания')
status = models.IntegerField(choices=Status.choices, default=0)
def status_name(self):
return dict(Status.choices).get(self.status)
def update_url(self):
return reverse('poll_update', args=(self.id, ))
forms.py
QuestionInlineFormSet = inlineformset_factory(Poll, Question, extra=1, can_delete=False,
fields=('type', 'text', 'poll'),
widgets={
'type': w.Select(attrs={'class': 'form-control'}),
'text': w.TextInput(attrs={'class': 'form-control'}),
})
class PollForm(CommonForm):
class Meta(CommonForm.Meta):
model = Poll
views.py
class Create(BaseCreateView):
template_name = 'back/poll/poll.html'
page_title = 'Создание опроса'
model = Poll
form_class = PollForm
def form_valid(self, form):
result = super(Create, self).form_valid(form)
questions_formset = QuestionInlineFormSet(data=form.data, instance=self.object, prefix='questions_formset')
if questions_formset.is_valid():
questions_formset.save()
return result
def get_context_data(self, **kwargs):
context = super(Create, self).get_context_data(**kwargs)
context['questions_formset'] = QuestionInlineFormSet(prefix='questions_formset')
return context
class Update(BaseUpdateView):
template_name = 'back/poll/poll.html'
page_title = 'Редактирование опроса'
model = Poll
form_class = PollForm
def form_valid(self, form):
result = super(Update, self).form_valid(form)
questions_formset = QuestionInlineFormSet(data=form.data, instance=self.object, prefix='questions_formset')
if questions_formset.is_valid():
questions_formset.save()
return result
def get_context_data(self, **kwargs):
context = super(Update, self).get_context_data(**kwargs)
context['questions_formset'] = QuestionInlineFormSet(instance=self.get_object(), prefix='questions_formset')
return context
poll.html
{% extends 'back/base/form/base.html' %}
{% block form %}
{% include "back/includes/status_buttons.html" %}
<div class="row">
<div class="col-md-7">
<div class="row" style="margin-bottom: 15px;">
<div class="col-md-12">
{% include 'back/includes/status_label.html' %}
</div>
</div>
{% include "back/base/form/field.html" with field=form.title %}
{% include "back/base/form/datetime_field.html" with field=form.date_from %}
{% include "back/base/form/datetime_field.html" with field=form.date_to %}
{{ questions_formset.management_form }}
{% for question_form in questions_formset %}
{% include "back/poll/question.html" with form=question_form %}
{% endfor %}
<div style="float: right; margin-right: 45px">
<button class="btn btn-success add-form-row">Добавить вопрос</button>
</div>
</div>
</div>
{% endblock %}
question.html
<div class="questions">
<div class="row form-row">
<div class="form-group col-md-5{% if form.type.errors %} has-error{% endif %}">
<label>{{ form.type.label }}</label>
{{ form.type }}
<p class="help-block">{{ form.type.errors }}</p>
</div>
<div class="form-group col-md-5{% if form.text.errors %} has-error{% endif %}">
<label>{{ form.text.label }}</label>
{{ form.text }}
<p class="help-block">{{ form.text.errors }}</p>
</div>
<div class="col-md-2" style="margin-top: 25px">
<button type="button" class="btn btn-danger remove-form-row">✕</button>
</div>
</div>
</div>
<script>
function updateElementIndex(el, prefix, ndx) {
let id_regex = new RegExp('(' + prefix + '-\\d+)');
let replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function deleteForm(prefix, btn) {
let total = parseInt($('#id_' + prefix + '_formset' + '-TOTAL_FORMS').val());
if (total > 1) {
btn.closest('.form-row').remove();
let forms = $('.form-row');
$('#id_' + prefix + '_formset' + '-TOTAL_FORMS').val(forms.length);
for (let i = 0, formCount = forms.length; i < formCount; i++) {
$(forms.get(i)).find(':input').each(function () {
updateElementIndex(this, prefix, i);
});
}
}
}
function cloneMore(selector, prefix) {
let newElement = $(selector).clone(true);
let total = $('#id_' + prefix + '_formset' + '-TOTAL_FORMS').val();
newElement.find(':input:not([type=button]):not([type=submit]):not([type=reset])').each(function () {
let name = $(this).attr('name').replace('-' + (total - 1) + '-', '-' + total + '-');
let id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
});
newElement.find('label').each(function () {
let forValue = $(this).attr('for');
if (forValue) {
forValue = forValue.replace('-' + (total - 1) + '-', '-' + total + '-');
$(this).attr({'for': forValue});
}
});
total++;
$('#id_' + prefix + '_formset' + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
}
$(document).on('click', '.add-form-row', function (event) {
event.preventDefault();
cloneMore('.form-row:last', 'questions');
})
$(document).on('click', '.remove-form-row', function (event) {
event.preventDefault();
deleteForm('questions', $(this));
});
</script>
Here's a photo of what it should look like
Again, I want it to be possible to add questions, remove them, save the form. And after I click on the poll in the list of all polls and go to it's edit page I want already added questions to be there.
UPDATE
Found solution to MultiValueDictKeyError in this post
How to debug a Django MultiValueDictKeyError on Formset POST
Now the only problem I have is removing Questions from Poll. My delete button works, it removes the form from page, but after saving the document it reappears.

I cannot connect my form to my models for posting of grades

Models.py
class YearLevel(models.Model):
...
class Section(models.Model):
...
class Subject(models.Model):
...
class Student(models.Model):
first_name = models.CharField(max_length = 100, default = '')
last_name = models.CharField(max_length = 100, default = '')
year_level = models.OneToOneField(YearLevel, on_delete=models.SET_NULL, null = True)
section = models.OneToOneField(Section, on_delete=models.SET_NULL, null = True)
enrolled_subject = models.ManyToManyField(Subject)
parent = models.ForeignKey(Parent, on_delete=models.SET_NULL, null = True) #parent is from user models
class StudentGrade(models.Model):
PERIOD_CHOICES = [
...
]
student = models.ForeignKey(Student, on_delete=models.CASCADE,)
period = models.CharField(choices=PERIOD_CHOICES, max_length = 30)
subjects = models.ForeignKey(Subject, on_delete=models.CASCADE)
grade = models.DecimalField(default = 75.00, max_digits=4, decimal_places=2)
Views.py
def postgrade(request):
students = Student.objects.all().prefetch_related('enrolled_subject')
context = {
'students': students,
}
if request.method == "POST":
data = request.POST
grade_list = data.getlist('grade')
subject_list = data.getlist('subject')
student = Student.objects.get(pk= data.get('studentid')) #this is where they point my error
i=0
while i < len(grade_list):
enrolled_subject = Subject.objects.get(pk= subject_list[i])
new_grade = StudentGrade(student = student, period= data.get('period'), subjects = enrolled_subject, grade=grade_list[i])
new_grade.save()
i+= 1
Postgrade.html(template)
My queries are displaying properly, the problem is I get an error when i try to save the form
{% for students in students %}
<p>
<a class="btn btn-primary" data-bs-toggle="collapse" href="#collapse{{forloop.counter}}" role="button" aria-expanded="false" aria-controls="collapse{{forloop.counter}}">
{{students.first_name}} {{students.last_name}}
</a>
</p>
<div class="collapse" id="collapse{{forloop.counter}}">
<div class="card card-body">
<form method="POST" >
{% csrf_token %}
<input type="hidden" name="studentid" value="{{students.student.id}}">
<label for="period">Period:</label>
<select name="period" required>
<option selected>First Grading</option>
<option>Second Grading</option>
<option>Third Grading</option>
<option>Fourth Grading</option>
</select><br>
{% for subject in students.enrolled_subject.all %}
<input type="hidden" name="subject" value="{{subject.id}}">
<label for="{{subject.subject_name}}">{{subject.subject_name}}</label>
<input type="text" name="grade">
<br>
{% endfor %}
<button type="submit">upload grade</button>
</form>
</div>
</div>
{% endfor %}
My error says:
ValueError at /Information/postgrade/
invalid literal for int() with base 10: ''
and it points to my views.py:
student = Student.objects.get(pk= data.get('studentid'))
So i feel like there might be something wrong with my template or views, or maybe both
or I should drop out LOL
Thanks for the help

Django : modelformset not reflecting initial data

i am trying to create a form to edit skills of user where they have saved multiple no. of skills. after rendering the template input fields are empty but the no. of form created is correct as per queryset.
forms.py
class skillform(forms.ModelForm):
name = forms.CharField(label='Skill',widget=forms.TextInput(attrs={'class': 'form-control',}))
level = forms.ChoiceField(choices=(('Novice','Novice'),('Beginner','Beginner'),('Skillful','Skillful'),('Experienced','Experienced'),('Expert','Expert')),label="level",initial='Skillful',widget=forms.Select(),required=False)
class Meta:
model = userskills_model
fields = ('name','level')
skillformset = modelformset_factory(userskills_model, form = skillform, extra=0, can_delete=False)
models.py
class userskills_model(models.Model):
userid = models.ForeignKey(user_model, on_delete=models.PROTECT)
skills =models.CharField(max_length=264,unique=False,blank=False,null=False)
skills_level = models.CharField(max_length=264,unique=False,blank=False,null=False)
def __str__(self):
return str(self.userid)
views.py
def skillview(request):
qset=userskills_model.objects.filter( userid=user_model.objects.get(userid=userid))
skillformset(queryset = qset)
if request.method == 'GET':
formset = skillformset(request.GET or None)
elif request.method == 'POST':
formset = skillformset(request.POST)
#validating and saving
return render(request, template_name, {
'formset': formset,
})
template/skills.html
{% extends 'app/base.html' %}
{% load staticfiles%}
{% block head %}
<link href="{% static "/css/skills.css" %}" rel="stylesheet"
type="text/css"/>
{% endblock %}
{% block content %}
<div class="heading_text">SKILLS</div>
<form class="form-horizontal" method="POST" action="">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
<div class="row form-row spacer">
<div class="col-5">
<label>{{form.name.label}}</label>
<div class="input-group">
{{form.name}}
</div>
</div>
<div class="col-5">
<label>{{form.level.label}}</label>
<div class="input-group">
{{form.level}}
<!-- <div class="input-group-append">
<button class="btn btn-success add-form-row">+</button>
</div> -->
</div>
</div>
<div class="input-group-append">
<button class="btn btn-success add-form-row">+</button>
</div>
</div>
{% endfor %}
<div class="row spacer">
<div class="col-3 button1">
<button type="submit" class="btn3">Save and Continue</button>
</div>
</div>
</form>
{% endblock %}
{% block custom_js %}
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script type="text/javascript">
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+)');
var replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for",
$(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);}
function cloneMore(selector, prefix) {
var newElement = $(selector).clone(true);
var total = $('#id_' + prefix + '-TOTAL_FORMS').val();
newElement.find(':input').each(function() {
var name = $(this).attr('name')
if(name) {
name = name.replace('-' + (total-1) + '-', '-' + total + '-');
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');}});
total++;
$('#id_' + prefix + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
var conditionRow = $('.form-row:not(:last)');
conditionRow.find('.btn.add-form-row')
.removeClass('btn-success').addClass('btn-danger')
.removeClass('add-form-row').addClass('remove-form-row')
.html('-');
return false;}
function deleteForm(prefix, btn) {
var total = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
if (total > 1){
btn.closest('.form-row').remove();
var forms = $('.form-row');
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
for (var i=0, formCount=forms.length; i<formCount; i++) {
$(forms.get(i)).find(':input').each(function() {
updateElementIndex(this, prefix, i);
});
}
}
return false;}
$(document).on('click', '.add-form-row', function(e){
e.preventDefault();
cloneMore('.form-row:last', 'form');
return false;});
$(document).on('click', '.remove-form-row', function(e){
e.preventDefault();
deleteForm('form', $(this));
return false;});
</script>
{% endblock %}
edit:added the template/skills.html . i m stuck with this please help me out here
The fields you have declared on your skillform do not exist on userskills_model so they won't be populated with anything. Try renaming the fields on your form to skills and skills_model so they match your model:
class skillform(forms.ModelForm):
skills = forms.CharField(label='Skill',widget=forms.TextInput(attrs={'class': 'form-control',}))
skills_level = forms.ChoiceField(choices=(('Novice','Novice'),('Beginner','Beginner'),('Skillful','Skillful'),('Experienced','Experienced'),('Expert','Expert')),label="level",initial='Skillful',widget=forms.Select(),required=False)
class Meta:
model = userskills_model
fields = ('skills','skills_level')
and update your template to reference form.skills and form.skills_level:
...
{% for form in formset %}
<div class="row form-row spacer">
<div class="col-5">
<label>{{form.skills.label}}</label>
<div class="input-group">
{{form.skills}}
</div>
</div>
<div class="col-5">
<label>{{form.skills_level.label}}</label>
<div class="input-group">
{{form.skills_level}}
...
I guess your qset is empty, try this -
qset=userskills_model.objects.filter( userid=self.request.user) # This for logged in user
For update case -
user = get_object_or_404(user_model, userid=userid)
qset=userskills_model.objects.filter( userid=user)