data not storing in database django - django

My first issue is data is not going in database.it is not showing any error but not storing as well.
and my second issue is that i am pre-populating the form field with query set in a drop-down but it is showing me the id(primary key) and i want show some other field.how can i do this?
my view
def payment(request):
#form = jobpostForm_first()
#country_list = Country.objects.all()
if request.POST:
form = jobpostForm_detail(request.POST)
if form.is_valid():
if '_Submit' in request.POST:
form.save()
return HttpResponseRedirect('/thanks/')
else:
form = jobpostForm_detail()
#form.fields['country'].queryset = Country.objects.all()
c = {}
c.update(csrf(request))
return render_to_response('portal/display.html',{
'form':form
},context_instance=RequestContext(request))
my modelform:
class jobpostForm_detail(ModelForm):
class Meta:
model = payment_detail
fields = ('payment_type','country')
def __init__(self, *args, **kwargs):
super(jobpostForm_detail, self).__init__(*args, **kwargs)
self.fields['country'].queryset = Country.objects.all()
self.fields['payment_type'].queryset = Payment_types.objects.all()
self.helper = FormHelper()
self.helper.form_class = 'horizontal-form'
self.helper.form_id = 'id-jobpostform'
self.helper.form_class = 'blueForms'
self.helper.form_method = 'post'
self.helper.add_input(Submit('submit_addcontent', 'Pay'))
super(jobpostForm_detail, self).__init__(*args, **kwargs)
My template:
<form method="post" action="/portal/next/post/" class="blueForms" id="id-jobpostform">
{% csrf_token %}
{% crispy form %}
</form>

Why are you checking for "_Submit" in your view?
I suggest you read how to use a form in a view, especially the comments:
...
def contact(request):
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
...
In your case, you just need to call form.save() after form.is_valid()
Question for you: can you please explain this bit of code in your form class? typo, I suppose?
widgets = {
}),
}

Related

Instance of djaform not updating

I have the next form in Django:
class Medical(forms.ModelForm):
worker= forms.ModelChoiceField(
queryset=Worker.objects.none(),
empty_label=None,
widget=forms.Select(attrs={'class': 'form-control'})
)
description=forms.CharField(
widget=forms.Textarea(attrs={'class': 'form-control'})
)
upload=forms.FileField(
widget=forms.FileInput(attrs={'class': 'form-control'})
)
class Meta:
model = Medical_Issue
fields = (
'worker',
'description',
'upload',
)
def __init__(self, *args, **kwargs):
user_id = kwargs.pop('user_id')
method=kwargs.pop('method')
super().__init__(*args, **kwargs)
self.fields['worker'].queryset = Worker.objects.filter(user_id=user_id)
def save(self, commit=True):
m = super(Medical, self).save(commit=False)
m.worker=self.cleaned_data['worker']
m.description=self.cleaned_data['description']
m.upload=self.cleaned_data['upload']
if commit:
m.save()
return m
And following views:
def medical_list(request):
worker=Worker.objects.filter(user_id=request.user.id).get()
issues=Medical_Issue.objects.filter(worker=worker.id).order_by('-created_at')
return render(request,'medical_list.html', {'medical_issues':issues})
def medical_add(request):
print(request.user.id)
if request.method == "POST":
form = Medical(request.POST,request.FILES,user_id=request.user, method= 'ADD')
if form.is_valid():
form.save()
return redirect('medical_list')
else:
form = Medical(user_id=request.user, method= 'ADD')
return render(request, 'medical_add.html', {'method':'ADD','form': form})
def medical_edit(request,id_issue):
worker=Worker.objects.get(user_id=request.user)
issues=Medical_Issue.objects.filter(worker=worker).order_by('-created_at')
issue= Medical_Issue.objects.get(id=id_issue)
if request.method == 'GET':
form = Medical(user_id=worker.user_id,instance=issue, method= 'EDIT')
else:
form = Medical(request.POST, request.FILES, user_id=worker.user_id, method= 'EDIT')
if form.is_valid():
form.save()
return redirect('medical_list')
return render(request,'medical_add.html', {'method':'EDIT','form': form})
Main probles is when adding, it saves record just fine, but when editing, it is creating a new instance of the issue.
I´m trying to make it modifying save method on form, but maybe it´s not the right approach? With thata said, I have tried to add an id field to the form, but same results from this
Thanks
I suspect that you don't pass the correct instance value to the form in your medical_edit view:
issue= Medical_Issue.objects.get(id=id_issue)
if request.method == 'GET':
form = Medical(
user_id=worker.user_id,
instance=issue, # <-- issue or parte?
method='EDIT'
)
UPDATE
It should also include the instance argument in the POST method.
if request.method == 'GET':
# ...
else:
form = Medical(
request.POST,
request.FILES,
instance=issue, # <--
user_id=worker.user_id,
method= 'EDIT'
)

Not able to submit django form

I don't know why my form is invalid. Despite everything seems to be normal. I am not getting any error. sending you screenshot of models.py
Here is my forms.py
class LeadForm(forms.ModelForm):
product_queryset = []
product_name = forms.MultipleChoiceField(choices=product_queryset, required=False)
contact = PhoneNumberField()
def __init__(self, *args, **kwargs):
super(LeadForm, self).__init__(*args, **kwargs)
self.fields["product_name"].choices = [(pro.get('id'), pro.get('name')) for pro in
Products.objects.all().values('id', 'name')]
class Meta:
model = Lead
exclude = ('created_at','created_by')
widgets = {
'date_of_enquiry': DateInput(attrs={'type': 'date'})
}
Here is my views.py
def create_lead(request):
u = User.objects.get(username=request.user.get_username())
if request.method == 'POST':
print(request.POST)
# form = LeadForm()
form = LeadForm(request.POST)
if form.is_valid():
print('inside valid')
form.save(commit=True)
form.created_by = u
form.save()
form = LeadForm()
context = {"form": form}
return render(request, 'create_lead.html', context)
You should render the errors you are getting, to do that you need to send to template:
def create_lead(request):
form = LeadForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
instance = form.save(commit=False)
instance.created_by = request.user
instance.save()
return redirect('/sucess_url')
context = {"form": form}
return render(request, 'create_lead.html', context)
And render the errors in template:
{% for field in form %}
{{ field.errors }}
{% endfor %}
More information can be found in documentation regarding form error rendering.
Probably you should remove the __init__ method from Form class, instead add a __str__ method in Product model:
class Product(models.Model):
# rest of the code
def __str__(self):
return self.name
Please do in your forms.py
class Meta:
model = Lead
exclude = ('created_at','created_by')
fields = ('product_name', [and all your fields which you want to include])
widgets = {
'date_of_enquiry': DateInput(attrs={'type': 'date'})
}

create help text for a field dynamically

I have my response form and view like this
class ResponseForm(ModelForm):
class Meta:
model = ResponseModel
exclude = ('author', 'title','submit_count')
# help_texts = {
# 'ans1': user.q1.value,
# }
#login_required
def ResponseFormView(request):
if request.method == "POST":
form = ResponseForm(request.POST)
if form.is_valid():
submission = form.save(commit=False)
submission.author = request.user
submission.save()
return render(request, 'thanks.html', {})
else:
form = ResponseForm()
return render(request, 'response_tem.html', {'form': form})
I want the help text for 'ans1' field to be the value of q1 field of request.user. How do I do it?
You can do it like this:
class ResponseForm(ModelForm):
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None) # popping user from known arguments
super(ResponseForm, self).__init__(*args, **kwargs)
if user:
self.fields['ans1'].help_text = "Help Text for {}".format(user.username)
class Meta:
model = ResponseModel
exclude = ('author', 'title','submit_count')
#login_required
def ResponseFormView(request):
if request.method == "POST":
form = ResponseForm(request.POST)
if form.is_valid():
submission = form.save(commit=False)
submission.author = request.user
submission.save()
return render(request, 'thanks.html', {})
else:
form = ResponseForm(user=request.user) # passing user as known argument
return render(request, 'response_tem.html', {'form': form})
Here, in the view I am passing the request.user as known argument when I am initiating Form Class's Object (marked with comment). Then in the Form, I am catching the user sent from view and updating the field's help text.

Django two separate forms under single page / url

I have two forms which I want to display and use on index page of the website.
Index page is a HomeView which in it's context contains two forms - ContactForm and SubscribtionForm.
My goal is to use these two forms on single page. So far it is impossible because each time validation fails it redirects me to view which is responsible for form validation.
Fragment of index page html code:
<form id="contact-form" class="contact form-horizontal" action="{% url 'contact' %}" method="post" novalidate>
<form id="newsletter-form" class="newsletter_form" action="{% url 'subscribe' %}" method="post" novalidate>
How do I do it in django that when I submit it will use other views to validate and save the data but responses will be displayed on Index page? Should I use javascript/ajax calls to solve this issue? Or there is another way?
Edit:
class SubscriberFormView(FormView):
form_class = SubscriberForm
template_name = 'home/subscriber_form.html'
def get_success_url(self):
return reverse('home')
def form_valid(self, form):
form.save()
return redirect(self.get_success_url())
class ContactFormView(FormView):
form_class = ContactForm
template_name = "home/contact_form.html"
def form_valid(self, form):
instance = form.save()
instance.send_confirmation()
instance.send_notification()
return redirect(self.get_success_url())
Alternative solution with prefixes:
class HomeView(FormMixin, TemplateView):
template_name = 'index.html'
form_class = ContactForm
form_class_sub = SubscriberForm
def get_success_url(self):
return reverse('home')
def get_forms(self):
contact_kwargs = self.get_form_kwargs().copy()
contact_kwargs['prefix'] = 'contact'
sub_kwargs = self.get_form_kwargs().copy()
sub_kwargs['prefix'] = 'sub'
return {
'contact_form': self.form_class(**contact_kwargs),
'subscription_form': self.form_class_sub(**sub_kwargs),
}
def post(self, request, *args, **kwargs):
forms = self.get_forms()
if 'contact-submit' in request.POST:
form = forms['contact_form']
form_name = 'contact_form'
elif 'newsletter-submit' in request.POST:
form = forms['subscription_form']
form_name = 'subscription_form'
else:
raise Http404
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form, form_name)
def form_invalid(self, form, form_name):
return self.render_to_response(self.get_context_data())
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
if 'contact_form' not in data:
data['contact_form'] = self.get_forms()['contact_form']
if 'subscription_form' not in data:
data['subscription_form'] = self.get_forms()['subscription_form']
return data
def form_valid(self, form):
instance = form.save()
return super().form_valid(form)
Function based view (index):
def index(request):
contact_form = ContactForm(request.POST or None, prefix='contact')
subscription_form = SubscriberForm(request.POST or None, prefix='sub')
if request.method == "POST":
if 'contact-submit' in request.POST:
form = contact_form
elif 'sub-submit' in request.POST:
form = subscription_form
else:
raise Http404
if form.is_valid():
form.save()
return TemplateResponse(request, template="index.html", context={
'contact_form': contact_form,
'subscription_form': subscription_form,
})
Final version:
def index(request):
contact_form = ContactForm(None, prefix='contact')
subscription_form = SubscriberForm(None, prefix='sub')
if request.method == "POST":
if 'contact-submit' in request.POST:
contact_form = ContactForm(request.POST, prefix='contact')
if contact_form.is_valid():
contact_form.save()
elif 'sub-submit' in request.POST:
subscription_form = SubscriberForm(request.POST, prefix='sub')
if contact_form.is_valid():
contact_form.save()
else:
raise Http404
return TemplateResponse(request, template="index.html", context={
'contact_form': contact_form,
'subscription_form': subscription_form,
})
You should not use different view do validate data. The forms should be validated in the same view where they've been rendered.
To be able to use multiple forms in one view, simply use form prefix:
https://docs.djangoproject.com/en/1.8/ref/forms/api/#prefixes-for-forms

How to define initial values for ModelForm rightly?

I have no idea and I need to ask your advice.
I have simple form:
class CommentForm(ModelForm):
class Meta:
model = Comment
fields = ['text','author','news']
I want to add form in DetailView and hadle this form there:
class NewsDetailView(DetailView):
model = News
template_name = 'news/detail.html'
def get_initial(self):
return {'news': self.get_object(), 'author': self.request.user}
def get_context_data(self, **kwargs):
context = super(NewsDetailView, self).get_context_data(**kwargs)
context['form'] = CommentForm(initial=self.get_initial())
return context
def post(self, request, *args, **kwargs):
'''
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
comment_form.save()
I don't want to show 'author' and news fieds. But if I hide them I can't to get initial values..
UPDATED:
After form validation I need return current form instance in the template through updating page. I attempted the next:
comment_form = CommentForm(request.POST, request=request)
if comment_form.is_valid() and comment_form.validate_user():
comment_form.save()
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
else:
context = super(NewsDetailView,self).get_context_data(**kwargs)
context['form'] = comment_form
return self.render_to_response(context)
But did not work.
If you don't render your fields using {{ form.author }} and {{ form.news }} the form won't validate. Try using a HiddenInput for each field, You can do that by overriding the __init__ method of your form:
class CommentForm(ModelForm):
def __init__(self, *args, **kwargs):
super(CommentForm, self).__init__(*args, **kwargs)
self.fields['author'].widget = forms.HiddenInput()
self.fields['news'].widget = forms.HiddenInput()
class Meta:
model = Comment
fields = ['text','author','news']