django form is invalid but has no errors - django

my datefields in my django form render always as invalid, but no errors of the how and why are given. (I use both non_field_errors as field.errors )
My Form
class FilterJournalForm(forms.Form):
end_initial = datetime.now(utc)
from_initial = (end_initial - timedelta(days=30))
from_date = forms.DateField(
widget=forms.DateInput(format='%m-%d-%Y'),
initial=from_initial,
required=True,
)
end_date = forms.DateField(
widget=forms.DateInput(format='%m-%d-%Y'),
initial=end_initial,
required=True,
)
part of my view that has the form:
filter_form = FilterJournalForm(request.POST or None)
if request.POST:
print request.POST
if filter_form.is_valid():
print "success"
My template part:
<form class="form-inline" action="" method="POST">
{% csrf_token %}
<div class="form-group">
{{ filter_form.from_date|add_css_class:"form-control input-sm" }}
</div> until
<div class="form-group">
{{ filter_form.end_date|add_css_class:"form-control input-sm" }}
</div>
<button type="submit" class="btn btn-primary btn-sm" >Filter</button>
{% if filter_form.errors %}
<div id="form-error">
<p>The operation could not be performed because one or more error(s) occurred.<br />{{ filter_form.non_field_errors }}</p>
<ul>
{% for field in form %}
<li>{{ field.errors|striptags }}</li>
{% endfor %}
</ul>
</div>
Any idea what is going wrong here? (i also tried to change the initial input of my formfields to date.today() to see if datetime objects could be ruining it. But that as well is not the problem.
{% endif %}

Related

django let's me save a model correctly via admin but not form/shell

I am having difficulty saving a Django model instance into my db. The instance consists of a FileField, which I think is what is causing the difficulty. My model is as follows:
class initial_settings(models.Model):
name = models.CharField(max_length=30, unique=True)
epsilon = models.FloatField(default = 0.3)
document = models.FileField(upload_to='documents/')
def __str__(self):
return self.name
And when I open up a shell, create an instance, and save, I then run the command
test = initial_settings(name = 'test1234', epsilon = 3, document = 'doc.csv').save()
pd.DataFrame(csv.reader(open(test.document.path, 'r')))
Gives me an error, No such file or directory . But, if I open up the admin console and create an instance, it saves correctly and I am able to load it from shell. In the admin console, I can see that the instance created in shell is not being saved to the correct location ('media/documents') but instead direct to root dir, but I am not sure why. Any assistance is appreciated!
P.S:
Settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
Edit: adding view and template:
views.py
FORMS_REG = [("doc_step1", Doc_form_1),
("doc_step2", Doc_form_2),
]
TEMPLATES = {"doc_step1": "doc_step_1.html",
"doc_step2": "doc_step_2.html",
}
class Forecast_Wizard(SessionWizardView):
def get_template_names(self):
return [TEMPLATES[self.steps.current]]
instance = None
def get_form_instance( self, step ):
if self.instance is None:
self.instance = initial_settings()
return self.instance
file_storage = FileSystemStorage(location=settings.MEDIA_ROOT)
def done(self, FORMS_REG, **kwargs):
model_name = self.get_cleaned_data_for_step('doc_step2')['name']
self.instance.save()
doc_obj = initial_settings.objects.get(name = name)
return redirect('home')
templates (doc_step1 and doc_step2 use the same template code):
<body>
<div class="container">
<!--Row with two equal columns-->
<div class="row">
<div class="col-lg-1 col-md-1 col-xl-1 col-sm-1">
</div>
<div class="col-lg-4 col-md-4 col-xl-4 col-sm-12">
<br>
<br>
<br>
<br>
<div class="card">
<div class="card-body">
<p class = "card-text">Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
{% for field in form %}
{{field.error}}
{% endfor %}
<form action="" method="post">{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
{{ wizard.form }}
{% endif %}
</table>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" class="btn btn-dark" type="submit" value="{{ wizard.steps.first }}">first step</button>
<button name="wizard_goto_step" class="btn btn-dark" type="submit" value="{{ wizard.steps.prev }}">prev step</button>
{% endif %}
<input class="btn btn-dark" type="submit" value="submit"/>
</form>
</div>
</div>
</div>
<div class="col-lg-1 col-md-1 col-xl-1 col-sm-1">
</div>
</div>
</div>
</body>
I figured it out, was a pretty simple error. The form type on my template was wrong. I needed
<form enctype="multipart/form-data" action="" method="post">{% csrf_token %}
instead of just
<form action="" method="post">{% csrf_token %}

How to show django form in django template?

I am trying to create a form using django and css.
views.py
from django.shortcuts import render
from .forms import ContactForm
def home(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
pass
else:
form = ContactForm()
return render(request, 'home.html', {'form':form})
forms.py
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length = 30)
email = forms.EmailField(max_length = 254)
message = forms.CharField(max_length = 2000, widget = forms.Textarea(),help_text = "Write Your Message here")
def clean(self):
cleaned_data = super(ContactForm, self).clean()
name = cleaned_data.get('name')
email = cleaned_data.get('email')
message = cleaned_data.get('message')
if not name and not email and not message:
raise forms.ValidationError('You have to write something!')
When I try to add the form to my html page like the following it doesn't show up. Just the button shows up, no form fields -
{% extends 'store/main.html' %}
{% load static %}
{% block content %}
<h3>Store</h3>
<form method = "post" novalidate>
{% csrf_token %}
{{ form }}
<button type='submit'>Submit</button>
</form>
{% endblock content %}
If I do css form instead it obviously show up the way it should.
{% extends 'store/main.html' %}
{% load static %}
{% block content %}
<h3>Store</h3>
<form>
<label for="fname">First Name</label>
<input type="text" id="fname" name="fname">
<button type='submit'>Submit</button>
</form>
{% endblock content %}
So I decided to add the form fields individually to the css form. Where does the {{form.name}} or {{form.email}} tag go?
EDIT:
Hey Vivek, the contact form code is this -
class ContactForm(forms.Form):
name = forms.CharField(max_length = 30)
email = forms.EmailField(max_length = 254)
message = forms.CharField(max_length = 2000, widget = forms.Textarea(),help_text = "Write Your Message here")
The html template looks like this-
{% extends 'store/main.html' %}
{% load static %}
{% block content %}
<h3>Store</h3>
<form method = "post" novalidate>
{% csrf_token %}
<label class="float-left" for="name">Name</label>
{{ form.name }}
<button type='submit'>Submit</button>
</form>
{% endblock content %}
Thanks for any input.
Accessing form fields individually will make you to render the form errors individually as well. {{form}} encapsulates everything:- Form fields , errors, non_field_errors..So if you have to access the fields individually do not forget to add the form errors.
I have written a sample code which will server the purpose.
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger" style="text-align:left">
<ul>
{% for field in form %}
{% for error in field.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="form-row">
<div class="col-md-4 mb-3">
<label class="float-left" for="id_name">Name</label>
{{ form.name }}
</div>
<div class="col-md-8 mb-3">
<label class="float-left" for="id_email">Email ID</label>
{{ form.email }}
</div>
</div>
<br>
<input type="submit" class="btn btn-primary" value="Pay" id="submit">
</form>

django model formset factory how to write {{ form.field }}

So for forms, if you have quantity = IntegerField() in forms.py, then in the html file you can write {{ form.quantity }} to get the input for the quantity. How can do you the samething for modelformset_factory?
I've created a formset to ask the user for the item name and quantity. The item name is given by the loop. I need to move the modelformset factory inside the loop for each iteration, but I don't know how
#views.py
#for showing items
if (Items.objects.filter(item_category="Produce").exists()):
produce = Items.objects.filter(item_category="Produce", show=True, quantity__gte=1)
if (Items.objects.filter(item_category="Grains").exists()):
grains = Items.objects.filter(item_category="Grains", show=True, quantity__gte=1)
if (Items.objects.filter(item_category="Protein/Dairy").exists()):
protein_dairy = Items.objects.filter(item_category="Protein/Dairy", show=True, quantity__gte=1)
if (Items.objects.filter(item_category="extras").exists()):
extras = Items.objects.filter(item_category="extra items", show=True, quantity__gte=1)
#playing with formset
form_extras = Items.objects.filter(show=True).count()
formset = modelformset_factory(Cart, form=CustomerOrderForm,extra=form_extras)
form = formset(queryset=Items.objects.none())
if request.method == 'POST':
form = formset(request.POST)
#work on this
if form.is_valid():
print("is valid")
form = formset(request.POST)
instances = form.save(commit=False)
for instance in instances:
#item previously in cart
if (Cart.objects.filter(username=request.user, item_name=form.cleaned_data.get('item_name')).exists()):
cart_instance = Cart.objects.get(username=request.user, item_name=form.cleaned_data.get('item_name'))
cart_instance.quantity = cart_instance.quantity + form.cleaned_data.get('quantity')
cart_instance.save()
else:
#item never in cart, create new instance
item_instance = Items.objects.get(item_name=form.cleaned_data.get('item_name'))
Cart.objects.create(username=request.user, item_name=form.cleaned_data.get('item_name'), weight=item_instance.weight, quantity=form.cleaned_data.get('quantity'), description=item_instance.description, image=item_instance.image, price=item_instance.price, storage_type=item_instance.storage_type, item_category=item_instance.item_category, limit=item_instance.limit,)
timestamp = datetime.date.today()
messages.success(request,"Sucessfully added your items to your cart! " + str(timestamp))
return redirect('/')
else:
print("form not valid for cart")
form = formset()
user_produce_points = request.user.profile.produce_points
user_grain_points = request.user.profile.grain_points
user_protein_dairy_points = request.user.profile.protein_dairy_points
user_extras_points = request.user.profile.extra_items_points
Home.html:
#home.html
<form method="POST">
{% csrf_token %}
{{ form.management_form }}
{{form.as_p}}
<div class="row">
{% for item in produce %}
<div class="card" style="width: 18rem;">
<img src="/media/{{ item.image }}" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title text-center">
<b>{% if item.storage_type == "Frozen" %}
Frozen
{% endif %}
{{ item.item_name }} ({{ item.weight }} oz)</b></h5>
<h6 class ="card-title text-center" style="color:green;font-size: 16px;"><b>{{ item.price }} Produce
{% if item.price < 2 %}
Point
{% else %}
Points
{% endif %}
</b></h6>
<p class="card-text">{{ item.description }}</p>
<br><br>
<div class="input-quantity">
<input type="hidden" name="form-{{forloop.counter}}-item_name" value="{{ item.item_name }}">
{{form.quantity}}
{{form.item_name}}
{{form.field}}
Quantity: <input style="max-width:3em;" type="number" name="form-{{forloop.counter}}-quantity" pattern="[0-9]{3}" min="0" max="{{ item.limit }}">
</div>
</div>
</div>
{% endfor %}
<br>
<button type="submit" style="height:38px;" class="btn btn-primary btn-lg sharp" type="button">Add to Cart</button>
</form>
Django Docs always has a nice example, it always helps me.
You sadly didn't post (I'm assuming you didn't) the rest of the view function so I can only guess that form in the template refers to the formset created in the view and that is gets passed. And if it does, you would need to first create the for-loop before accessing it in name="form-{{forloop.counter}}-item_name". You could create it like this:
{% for form_line in form %}
<!--form_line rendering you have-->
<p>Form #{{ forloop.counter }}</p>
{{ form_line.quantity }}
{{ form_line.item_name }}
{{ form_line.field }}
{% endfor %}
In your template you also have the produce variable. I am unsure what that refers to, again, maybe because I can't see the whole view function.

Form data are updating in the database instead of INSERTING

I want store the form data into database but when I press the submit button, the rows in the database is updating instead INSERTING
from home page I am clicking the link called. fetch_faculty_subject which will retrieve some data from database and shows output as like dropdown list(in HTML ). again from form I am adding some data to the form and storing to the table called Mapped_faculty_n_subjects
this is my views.py
def fetch_faculty_subject(request):
faculties= facultyhours.objects.filter(user_id = request.user.id)
subjects= subject_code.objects.filter(user_id = request.user.id)
classname= class_number.objects.filter(user_id = request.user.id)
context1 = {
'faculties': faculties,
'subjects': subjects,
'classes': classname
}
return render(request, 'createtimetable_for_class/selecting_subjects_n_teachers.html', context1)
def store_the_faculty_subject(request):
userr = request.user.id
selected_class_name=request.POST["classname"]
selected_faculty_name=request.POST["facultyname"]
selected_subject_name=request.POST["subjectname"]
selected_total_hours_per_week=request.POST["totalhours"]
faculty_n_subject_db=Mapped_faculty_n_subjects(selected_class_name=selected_class_name,selected_faculty_name=selected_faculty_name,selected_subject_name=selected_subject_name,selected_total_hours_per_week=selected_total_hours_per_week,user_id=userr)
faculty_n_subject_db.save()
# return redirect('/fetch_faculty_subject/')
faculties= facultyhours.objects.filter(user_id = request.user.id)
subjects= subject_code.objects.filter(user_id = request.user.id)
classname= class_number.objects.filter(user_id = request.user.id)
context1 = {
'faculties': faculties,
'subjects': subjects,
'classes': classname
}
# return redirect(request,'createtimetable_for_class/selecting_subjects_n_teachers.html',context1)
return render(request, 'createtimetable_for_class/selecting_subjects_n_teachers.html',context1)
this is my models.py
class Mapped_faculty_n_subjects(models.Model):
selected_class_name=models.CharField(max_length=250,primary_key=True)
selected_faculty_name=models.CharField(max_length=250)
selected_subject_name=models.CharField(max_length=250)
selected_total_hours_per_week=models.CharField(max_length=250)
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
this is my html form
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row justify-content-center">
<div class="col-6">
<div class="card">
<div class="card-body">
<h2>Select Faculty and Subject</h2>
<form method="post" action="/store_the_faculty_subject/">
{% csrf_token %}
{{ form|crispy }}
<label>Select The Class</label><br>
<select name="classname">
{% for classes in classes %}
<option>{{ classes.class_name }}</option>
{% endfor %}
</select><br><br>
<label>Select The Faculty</label><br>
<select name="facultyname">
{% for faculty in faculties %}
<option>{{ faculty.faculty_name }}</option>
{% endfor %}
</select><br><br>
<label>Select The Subject</label><br>
<select name="subjectname">
{% for subjects in subjects %}
<option>{{ subjects.subject_name }}</option>
{% endfor %}
</select><br><br>
<label>Total hours per week</label><br>
<input type="number" max="34" name="totalhours" required class="textinput textInput form-control"><br>
<button type="submit" class="btn btn-primary">SUBMIT</button>
<a class="btn btn-secondary" href="#">NEXT</a>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

Django formset not rendering with django-widget-tweaks

I am getting the error 'LoginForm' object has no attribute 'as_widget' whenever I use formset. I really do not know what is the problem as the forms renders properly with normal Django forms. I am trying to see what characteristics in the formset is giving this problem with django-widget-tweaks, but up until now it is hard to figure out. I am getting the error at {% render_field field class="form-control" placeholder=field.label %} in the HTML code.
forms.py:
class LoginForm(ModelForm):
user_login = forms.HiddenInput()
prefix = 'prefix_login'
class Meta:
model = Usermie
fields = ['email', 'password']
widgets = {'password': forms.PasswordInput(),
'email': forms.EmailInput()}
views.py
def manage_articles(request):
article_formset = formset_factory(LoginForm)
book_formset = formset_factory(SignUpForm)
if request.method == 'POST':
if 'login' in request.POST:
login = article_formset(request.POST, request.FILES, prefix='login')
if login.is_valid():
email = request.POST.get('prefix_login-email', '')
password = request.POST.get('prefix_login-password', '')
# Return a user_obj object if the username and password are valid
# otherwise it will return null, the null variable is called None in python
user_obj = auth.authenticate(email=email, password=password)
# return HttpResponse("inside form if condition")
if user_obj is not None:
if user_obj.is_active:
login_usermie(request, user_obj)
return HttpResponseRedirect('/home/')
else:
# pass
return HttpResponse("Your account is inactive.")
elif 'signup' in request.POST:
signup = book_formset(request.POST, request.FILES)
if signup.is_valid():
pass
else:
login = article_formset
signup = book_formset
return render(request, 'usermie/formtest.html', {
'login': login,
'signup': signup,
})
HTML:
<div class="navbar navbar-default nav-links navbar-static-top page-nav">
<div class="container">
<a class="mini-navbar navbar-brand" href="/">
<img src="http://i.imgur.com/GAQSCtB.png" width="25"
alt="Driven Car Sales Logo"
class="img-rounded logo-nav mini-navbar" />
</a>
<ul class="nav navbar-nav nav-form-out pull-right">
<li>
<form class="navbar-form navbar-form-out login" action="" method="POST">
{% csrf_token %}
{% load widget_tweaks %}
{% for field in login %}
{% if login.errors %}
<div class="form-group">
<label class="sr-only" for="{{ field.auto_id }}">{{ field.label }}</label>
{% render_field field class="form-control" placeholder=field.label %}
{% if field == login.password %}
{% for hidden in field.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
<div class="help-block with-errors">{{ field.errors }}</div>
</div>
{% else %}
<div class="form-group">
<label class="sr-only" for="{{ field.auto_id }}">{{ field.label }}</label>
{% render_field field class="form-control" placeholder=field.label %}
{% if field == login.password %}
{% for hidden in field.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
</div>
{% endif %}
{% endfor %}
<div class="checkbox">
<label>
<input type="checkbox"> Remember me
</label>
</div>
<button type="submit" name="action" value="login" class="btn btn-default">Sign in</button>
</form>
</li>
</ul>
</div>
<form class="signup" method="POST" action="">
{% csrf_token %}
{{ signup.as_p }}
<button name='action' value='signup' type="submit">Sign up</button>
</form>
login variable in template is a formset. So when you do following:
{% for field in login %}
{% render_field field class="form-control" placeholder=field.label %}
{% endfor %}
you have form as field value and not a field.
Try do this:
{% for form in login %}
{% for field in form %}
{% render_field field class="form-control" placeholder=field.label %}
{% endfor %}
{% endfor %}