I'm having issues with time validation when submitting a form using django bootstrap datetime picker. When this form is submitted, I get a "Enter a valid time." error
models.py:
class Appointment(models.Model):
date = models.DateField()
time = models.TimeField()
forms.py:
valid_time_formats = ['%P', '%H:%M%A', '%H:%M %A', '%H:%M%a', '%H:%M %a']
date = forms.DateField(
widget=DateTimePicker(options={"format": "MM/DD/YYYY",
"pickTime": False,
"showToday": True,
}))
time = forms.TimeField(
widget=DateTimePicker(options={
"pickTime": True,
"pickDate": False,
"minuteStepping": 1,
"sideBySide": True,
}),
input_formats = valid_time_formats
)
class Meta:
model = Appointment
fields = (
'date',
'time',
'duration',
'cost',
)
And if helpful, the template:
{% extends 'scheduling/base_scheduling.html' %}
{% load bootstrap3 %}
{% block title %}New Appointment{% endblock %}
{% block external %}
<link rel="stylesheet"
href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.css">
<link rel="stylesheet"
href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.js">
</script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.js">
</script>
{{ form.media }}
{% endblock %}
{% block content %}
{# Load CSS and JavaScript #}
{% bootstrap_css %}
{% bootstrap_javascript %}
{# Display django.contrib.messages as Bootstrap alerts #}
{% bootstrap_messages %}
{# Display a form #}
<h1>New Appointment for {{client.full_name}}</h1>
<form action="{% url 'client_appointment_add' client.id %}" method="post" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">
{% bootstrap_icon "save" %} Submit
</button>
{% endbuttons %}
</form>
{% endblock %}
I've had same error. Setting date format in forms is not enough.
I get rid of it after properly configuring my django datetime settings.
For how to do it right see my answer here: How to format DateTimeField in Django Admin to localtime?
You will find there also link to example project with right config.
I tested this now with bootstrap3_datetime, bootstrap3 and it works, so it should work for you too.
Related
I aim to redirect the view after the form has been saved. However django keeps throwing a NoReverseMatch error. Is there a step that I've missed or a misconfiguration?
views.py
def add_carpet(request):
context_dict = {}
carpet_form = forms.CarpetForm()
if request.method == "POST":
carpet_form = forms.CarpetForm(request.POST)
if carpet_form.is_valid():
carpet = carpet_form.save()
return redirect(reverse(
"dashboard_add_images",
kwargs={
"model_type": "carpet",
"id": carpet.id
}
))
context_dict["carpet_form"] = carpet_form
return render(
request,
'dashboard/add_carpet.html',
context_dict
)
def add_images(request, model_type, id):
...
add_images.hml
{% extends 'layouts/dashboard_base.html' %}
{% load django_bootstrap5 %}
{% load static %}
{% block title %}Add Images{% endblock title %}
{% block content %}
<div class="row">
<div class="col justify-content-end">
<h1 class="heading half_space text-muted">
Add Images for the {model}
<span class="divider-left"></span>
</h1>
</div>
</div>
{# Load CSS and JavaScript #}
{% bootstrap_css %}
{% bootstrap_javascript %}
{# Display django.contrib.messages as Bootstrap alerts #}
{% bootstrap_messages %}
{# Display a form #}
<form enctype="multipart/form-data" action="{% url 'dashboard_add_images' %}" method="post" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% bootstrap_button button_type="submit" content="OK" %}
</form>
{% endblock content %}
From above you can see I added the enctype on the form but still no change.
urls.py
urlpatterns = [
path('add_carpet', views.add_carpet, name="dashboard_add_carpet"),
path('add_images/<str:model_type>/<uuid:id>', views.add_images, name="dashboard_add_images"),]
An example redirect url after a form has been submitted is this:
http://127.0.0.1:8000/dashboard/add_images/carpet/97afd259-6ec4-48fc-869f-2a00bbe29c70
Error:
Reverse for 'dashboard_add_images' with no arguments not found. 1 pattern(s) tried: ['dashboard/add_images/(?P<model_type>[^/]+)/(?P<id>[^/]+)$']
I was working a project on mine, in which I needed to provide a class to a field in form which is a input box, but don't know how to do so.
My Template:
{% extends 'diary/base.html' %}
{% block title %}Register{% endblock title %}
{% block content %}
{% load staticfiles %}
<link rel= "stylesheet" type= "text/css" href = "{% static 'users/register.css' %}">
<div id="login-box">
<div class="left-box">
<h1>Register</h1>
<form action="{% url 'register' %}" method="post">
{% csrf_token %}
{% for non_field_error in form.non_field_errors %}
<p>{{ non_field_error }}</p>
{% endfor %}
{% for field in form %}
{{ field }}
{% for error in field.errors %}
<p>{{ error }}</p>
{% endfor %}
{% endfor %}
<input type="submit" value="SIGN UP" name="signup-button" class="signup-btn">
</form>
</div>
<div class="right-box">
</div>
</div>
{% endblock content %}
In this specific part:
{% for field in form %}
{{ field }}
{% for error in field.errors %}
I want to provide a class to {{ field }}.
I tried this:
{{ field(class="txtb") }}
This is how I use to provide a class in Flask, but in Django this didn't worked.
Any Help Would Be Appreciated!
django-widget-tweaks
I'm using django-widget-tweaks module for set HTML attribute in templates.
installation
install module using pip install django-widget-tweaks
add to INSTALLED_APPS in settings.py
INSTALLED_APPS = [
...
'widget_tweaks',
...
]
{% load widget_tweaks %} in templates file
usage
in templates code:
{% load widget_tweaks %}
...
{% for field in form %}
{% render_field field class="txtb" %}
...
in HTML, looks like this:
<input class="txtb" ... ...>
reference django-widget-tweaks github page for more information.
manually
Detailed description is in here
forms.py:
class YourForm(forms.ModelForm):
modelfield = forms.CharField(
...,
widget=forms.TextInput(
attrs={
'class': 'txtb'
}
}
)
class Meta:
model = ...
fields = ...
And I have a lot of information about django to simpleisbetterthancomplex.com
django-widget-tweaks also learned here
I am using wagtail on django and creating a page where I will create questions and allow students to answer it by typing in the input box. I am using inline field where the wagtail gives me the option to choose various input option like(singleline, multiline, radio button etc). For my questions, I am choosing a singleline option. The problem I am facing is with the text box, the text box is too small, is there a way to increase the size(width) of the text box.
model.py
class QuestionPage(AbstractForm):
intro = RichTextField(blank=True)
thank_you_text = RichTextField(blank=True)
points_for_this_activity = models.IntegerField(blank=True, default=0)
content_panels = AbstractEmailForm.content_panels + [
FieldPanel('intro', classname="full"),
InlinePanel('form_fields', label="Create your question"),
FieldPanel('points_for_this_activity', classname="title"),
FieldPanel('thank_you_text', classname="full"),
]
question.html
<div class ="container">
<h1>{{ page.title }}</h1>
{% if user.is_authenticated and user.is_active or request.is_preview %}
{% if form %}
<div>{{ page.intro|richtext }}</div>
<form action="{% pageurl page %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input class="btn-md btn-primary" type="submit">
</form>
{% else %}
<div>You have already answered this. Go to the next question.</div>
{% endif %}
{% else %}
<div>To fill in the form, you should log in.</div>
{% endif %}
{% endblock %}
</div>
I am new to Django and don't understand what really is causing this:
I have a Model Company which has an OneToOneField, creator.
# models.py
class Company(models.Model):
class Meta:
verbose_name = 'Company'
verbose_name_plural = 'Companies'
creator = models.OneToOneField(User, related_name="company", on_delete=models.CASCADE, unique=False, null=True)
name = models.CharField(max_length=50)
I have a TemplateView class to handle get and post requests for creating a Company model:
# views.py
class create_company(TemplateView):
def get(self, request):
form = CompanyCreateForm()
title = "Some form"
return render(request, "form.html", {"form": form, "title": title})
def post(self, request):
form = CompanyCreateForm(request.POST)
if form.is_valid():
comp = form.save(commit=False)
comp.creator = request.user
comp.save()
return redirect('index')
The form is showing correctly also storing when I submit, the problem I am facing is with base.html where I show {% user.company %}; the form template extends it like:
{% extends "account/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="container">
<form method="post" action="">
{% csrf_token %}
{{form|crispy}}
<button class="btn btn-success" type="submit">Save</button>
</form>
<br>
</div>
<br>
{% endblock %}
and in base.html I access
{% if user.is_authenticated %}
{% user.company %}
{% endif %}
But user.company is not showing even it is set; it shows only when I redirect to index but not when I render the form.
Can someone help me understand what causes this?
{% if request.user.is_authenticated %}
{% request.user.company %}
{% endif %}
you are not sending any context to the base.html, thus only user wont work.
This was the error when I simulated your code.
Error during template rendering
In template /home/user/django/drf_tutorial/snippets/templates/base.html, error at line 2
Invalid block tag on line 2: 'user.company', expected 'elif', 'else' or 'endif'. Did you forget to register or load this tag?
1 {% if user.is_authenticated %}
2 {% user.company %}
3 {% endif %}
4 {% block content %}{% endblock %}
It gives hint that the code to show company should be variable {{ }} instead of tag {% %}. So the base.html template should be as below.
{% if user.is_authenticated %}
{{ user.company }}
{% endif %}
{% block content %}{% endblock %}
In some of my blog posts using django and markdown2, I am trying to include a form as follows:
views.py:
def post_detail(request, slug=None):
instance = get_object_or_404(Post, slug=slug)
if not instance.published:
raise Http404
return render(request, "posts/post_detail.html", {'instance': instance})
My template post_detail.html contains a {{ instance.get_markdown }} variable:
{% extends "base.html" %}
{% block body_content %}
<div>
{{ instance.get_markdown }}
</div>
{% endblock body_content %}
base.html:
<html>
<body>
{% block body_content %}
{% endblock body_content %}
</body>
</html>
models.py:
import markdown2
class Post(models.Model):
...
text = models.TextField(verbose_name=_("Text"))
...
def get_markdown(self):
return mark_safe(markdown2.markdown(self.text))
Example for a saved text in Post:
### Example
<form method = "POST">
{% csrf_token %}
First name:<input type="text" name="firstname">
<input type="submit" value="Submit">
</form>
This way, the page simply shows the string "{% csrf_token %}" within the form. How can I render the post with csrf protection?
My temporary solution is:
post_detail.html:
{% extends "base.html" %}
{% block body_content %}
<div>
{{ instance.get_markdown_text }}
</div>
{% if instance.form %}
<div>
<form method = "POST">{% csrf_token %}
{{ instance.get_markdown_form }}
</form>
</div>
{% endif %}
{% endblock body_content %}
models.py:
import markdown2
class Post(models.Model):
...
text = models.TextField(verbose_name=_("Text"))
form = models.TextField(verbose_name=_("Form"), blank=True, null=True)
...
def get_markdown_text(self):
return mark_safe(markdown2.markdown(self.text))
def get_markdown_form(self):
return mark_safe(markdown2.markdown(self.form))
I'm not very happy with this solution, because of the unnecessary field "form" and method get_markdown_form in Post and post_detail.html.