I'm trying to implement DateTimeLocalField in Flask WT Forms however the field does not return data. The other fields work fine.
from flask_wtf import FlaskForm
from wtforms.fields import DateTimeLocalField
class AddLegForm(FlaskForm):
origin_datetime = DateTimeLocalField('Origin Time')
In views.py:
#loads_blueprint.route('/add_leg/<load_id>', methods=['GET', 'POST'])
#login_required
def add_leg(load_id):
leg = db.session.query(Legs)
form = AddLegForm()
print(type(form.origin_datetime.data))
print(form.origin_datetime.data)
The print statements show:
<class 'NoneType'>
None
There are also StringField's in my form and all of the other data is there.
Minimal HTML:
<form method="POST", action="/loads/add_leg/{{load_id}}">
{{ form.hidden_tag() }}
<div class="form-outline mb-4">
{{ form.origin_datetime.label }}
{{ form.origin_datetime(class_="form-control", size=32) }}
</div>
<button type="submit" class="btn btn-primary float-end">Submit</button>
</form>
It might be a format issue, what if you use:
origin_datetime = DateTimeLocalField('Origin Time', format='%Y-%m-%dT%H:%M')
Related
I am trying to handle login/registration functionality in a modal. I got successful login/registration working by importing the LoginForm and RegistrationForm into my modal view and then posting to the appropriate allauth URLs. The desired behavior is to have forms with errors rendered asynchronously in the modal.
I have not been able to get forms with errors (email doesn't exist when trying to login, passwords don't match when registering etc.) to render as an html partial in a modal with the errors. I'm not too sure where to start when trying to add this functionality into my own view/how to piggyback on the allauth views and change their functionality.
Adding the below to my views.py and url.py I've managed to get the allauth default template to load when the form is invalid (e.g. email field does not contain a valid email) but have not been able to get my template to load.
From views.py:
class LoginViewSnippet(LoginView):
success_url = reverse_lazy('home')
template_name = 'user_app/partials/loginmodal.html'
def get_context_data(self, **kwargs):
print('here1')
context = super(LoginView,self).get_context_data(**kwargs)
return context
def form_invalid(self, form):
print('here')
error_msg = 'error'
return HttpResponse(error_msg, status=400)
login = LoginViewSnippet.as_view()
From urls.py:
path('accounts/login',user_app_views.login, name='account_login'),
From user_app/partials/loginmodal.html:
...
<div class="modal-body">
<form id="loginform" method="POST" action="{% url 'account_login' %}" autocomplete="off">
{% csrf_token %}
{% for field in loginform %}
<div class="form-group mb-3">
{{ field.errors }}
{{ field | as_crispy_field }}
</div>
{% endfor %}
</form>
</div>
<div class="mx-auto">
<button form="loginform"type="submit" class="btn btn-success" hx-post="{% url 'account_login' %}" hx-target="#modals-here">Login</button>
<button type="button" class="btn btn-secondary" onclick="closeModal()">Close</button>
</div>
...
I have a serch field on my page
<form method="GET" class="container mb-5">
<input type="search" class="form-control rounded" placeholder="Write a name" aria-label="Search"
aria-describedby="search-addon" name="search"/>
<button type="submit" class="btn btn-outline-primary px-5" >Search</button>
</form>
And here is my views
def my_view(request):
value_one = request.GET.get("search", None)
objects = MyModel.objects.all()
if value_one:
objects = objects.filter(field_one=value_one)
After I input something in a search field and push the button 'search', text which was in search field dissapears, I want it to stay until the next input. Is it possible to do with Django or not? Don't even know how to google it, everything I found was on different topic
on your template add value to your input:
<form method="GET" class="container mb-5">
<input type="search" class="form-control rounded" placeholder="Write a name" aria-label="Search" value="{{value_one"}}
aria-describedby="search-addon" name="search"/>
<button type="submit" class="btn btn-outline-primary px-5" >Search</button>
</form>
and on your view add that value to your context :
def my_view(request):
value_one = request.GET.get("search", None)
objects = MyModel.objects.all()
if value_one:
objects = objects.filter(field_one=value_one)
return render(request,'template.html',{'value_one':value_one,'objects':objects})
Have you heard of django's Form class ? You should be using the Form class to create forms in Django and that would allow you to preserve data between "submit" calls as well as handle errors. Some example code snippets for you:
forms.py
from django import forms
class SearchForm(forms.Form):
search = forms.CharField(label="Search Query", widget=forms.TextInput(attrs={"class": "form-control rounded", "placeholder": "Write a name", "aria-label": "Search", "aria-describedby": "search-addon"}))
views.py
from django.shortcuts import render
from .forms import SearchForm
def my_view(request):
form = SearchForm({"search": request.GET.get("search", None)})
if form.is_valid():
search_query = form.cleaned_data.get("search")
if search_query:
objects = MyModel.objects.filter(field_one=search_query).all()
# ...snip...
return render(request, 'searchform.html', {"form": form})
searchform.html
<form action="{% url 'my_view' %}" method="get">
{{ form }}
<input type="submit" value="Submit" class="btn btn-outline-primary px-5">
</form>
The post requests from the frontend do not get saved in the database, without any error shown. However, when I manually add entries from the admin panel, it shows on the frontend.
My index.html(form part):
<form class="main__input--form" method="POST">
{% csrf_token %}
<p class="main__input--text">
<textarea name="content" id="content" class="main__input--content" cols="35" rows="8" aria-label="Entry content" placeholder="Enter text here..."></textarea>
</p>
<button class="main__input--submit" type="submit">Vent</button>
</form>
My extension of index which loops through the database entries:
{% for obj in all_vents %}
<div>
<h1>{{obj.vent}}</h1>
</div>
<br />
{% endfor %}
My models.py:
class Vents(models.Model):
vent = models.CharField(max_length=10000)
def __str__(self):
return self.vent
My forms.py:
from django import forms
from .models import Vents
class VentForm(forms.ModelForm):
class Meta:
model = Vents
fields = ['vent']
My views.py:
from django.shortcuts import render, redirect
from .forms import VentForm
from .models import Vents
def ventout(request):
if request.method == "POST":
form = VentForm(request.POST or None)
if form.is_valid():
form.save()
return redirect("ventout")
else:
all_vents = Vents.objects.all()
return render(request, "ventout.html", {"all_vents": all_vents})
Views:
def ventout(request):
all_vents = Vents.objects.all()
if request.method == "POST":
form = VentForm(request.POST or None)
if form.is_valid():
form.save()
return redirect("ventout")
else:
form = VentForm()
context = {"all_vents": all_vents, "form":form}
return render(request, "ventout.html", context)
Template:
<form class="main__input--form" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="main__input--submit">Vent</button>
</form>
you could install/use "crispy_forms_tags" to make the form look better,
https://django-crispy-forms.readthedocs.io/en/latest/index.html
if you want to go further you could install/use "widget_tweaks"
https://pypi.org/project/django-widget-tweaks/
Your index.html from part should have {{ form }} form tag, as I guess.
Try Using following code
<form class="main__input--form" method="POST">
{% csrf_token %}
{{ form }}
<p class="main__input--text">
<textarea name="content" id="content" class="main__input--content"
cols="35" rows="8" aria-label="Entry content" placeholder="Enter text here...">
</textarea>
</p>
<button class="main__input--submit" type="submit" value="Submit">Vent</button>
</form>
In a Django project, I have used crispy forms to generate a form for a user to enter a title and a comment. For the comment section, I wish the user to be able to format their input (e.g add bold and italics tags, and also embed youtube videos, so use embed snippets). This is typical of a wordpress widget (admin) which allows text formatting for any text entry. Is it possible to do this with Django's Crispy forms, and if so, what is the best way forward? I am looking for suggestions for documentation, imports (any existing libraries compatible with Django?), as I as I couldn't find any, or an idea as to how to implement this manually. e.g. specifically, in which 'file' would it be implemented.
View of the html page (current)
View of the current form and text input on the comment area.
I've looked at the other questions-answers, but none answers this specifically.
This is the sort of functioanlity I would like to add to the form text input (for the content/comment box only)
Desired text input formatting options added
The current post_form.html code is below
{% extends "socialmedia/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Post your message</legend>
{{form|crispy}}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Post</button>
</div>
</form>
</div>
{% endblock content %}
post_detail.html
{% extends "socialmedia/base.html" %}
{% block content %}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{object.author.profile.image.url}}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'user-posts' object.author.username %}">{{ object.author }}</a>
<small class="text-muted">{{ object.date_posted|date:"F d, Y"}}</small>
{% if object.author == user %}
<div>
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'post-update' object.id %}"> Update </a>
<a class="btn btn-danger btn-sm mt-1 mb-1" href="{% url 'post-delete' object.id %}"> Delete </a>
</div>
{% endif %}
</div>
<h2 class="article-title">{{ object.title }}</h2>
<p class="article-content">{{ object.content }}</p>
</div>
</article>
{% endblock content %}
models.py (relevant to the form)
from django.db import models
from django.utils import timezone #don't forget to add this
from django.contrib.auth.models import User
from django.urls import reverse
class Post(models.Model):
title=models.CharField(max_length=100)
content=models.TextField(max_length=300)
date_posted=models.DateTimeField(default=timezone.now)
views.py (again relating to the form)
from django.shortcuts import render,get_object_or_404
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.auth.models import User
from .models import Post #import the Models Post
from django.views.generic import (
ListView,
DetailView,
CreateView,
UpdateView,
DeleteView
)
from django.http import HttpResponse
# Create your views here.
class PostListView(ListView):
model = Post #what model to query in order to create the list
template_name = 'socialmedia/home.html'
context_object_name = 'posts'
ordering = ['-date_posted']#the minus sign before the -date_posted makes it newest first
paginate_by = 10
class UserPostListView(ListView):
model = Post #what model to query in order to create the list
template_name = 'socialmedia/user_posts.html'
context_object_name = 'posts'
paginate_by = 10
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get('username'))
return Post.objects.filter(author=user).order_by('-date_posted')
class PostDetailView(DetailView):
model = Post
class PostCreateView(LoginRequiredMixin,CreateView):
model = Post
fields=['title','content']
def form_valid(self,form):
form.instance.author = self.request.user #set author to current loggged in user
return super().form_valid(form)
class PostUpdateView(LoginRequiredMixin,UserPassesTestMixin, UpdateView):
model = Post
fields=['title','content']
def form_valid(self,form):
form.instance.author = self.request.user
return super().form_valid(form)
#this only lets the user of the post update the post.....
def test_func(self):
post = self.get_object() #this gets the current post
if self.request.user == post.author:
return True
return False
class PostDeleteView(LoginRequiredMixin,UserPassesTestMixin, DeleteView):
model = Post
success_url = '/'
def test_func(self):
post = self.get_object() #this gets the current post
if self.request.user == post.author:
return True
return False
Why am I asking question despite already been asked? I read many question posted on Stack Overflow but I am not able to fix the code as I am new to Python Language.
What am I trying to do: Simply trying to take the input from user and return an HttpResponse (if successfully). Otherwise, an error HttpResponse message to return.
Problem : The MyForm.is_valid() in Forms.py is always returning False! I tried many solutions posted on previous questions and also read the documentary thrice but not able to understand, what am I doing wrong?
Views.Py
from django.http import HttpResponse
from .forms import PostForm
.
.
. <<code here>>
def register(request):
if request.method == 'POST':
Myform = PostForm(request.POST)
if Myform.is_valid():
return HttpResponse("<h1>Is_Valid is TRUE.</h1>")
else:
return HttpResponse("<h1>Is_Valid is False.</h1>")
else:
return HttpResponse("<h1> GET REQUEST>>>> </h1>")
Forms.Py
from django.forms import ModelForm
from .models import Post
class PostForm(ModelForm):
class Meta:
model= Post
fields = ['Username']
Models.Py
from django.db import models
class Post(models.Model):
Username = models.CharField(max_length = 20)
def __str__(self):
return self.name
HTML CODE
{% block body %}
<div class="container-fluid">
<form method="POST" class="post-form" action="{% url 'submit' %}">
{% csrf_token %}
<div class="form-group"> <!-- Full Name -->
<label for="Username" class="control-label">Full Name</label>
<input type="text" class="form-control" id="Username" name="full_name" placeholder="Enter the name of Patient here.">
</div>
<div class="form-group"> <!-- Submit Button -->
<button type="submit" class="btn btn-primary"> Submit!</button>
</div>
</form>
</div>
<hr/>
{% endblock %}
Urls.Py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^/submit$', views.register , name = 'submit'),
]
The name of your input should be username:
This is how you send this value to the form.
NOTE: It's better to use the django form, that you've already done with ModelForm
<input type="text" class="form-control" id="username" name="username" placeholder="Enter the name of Patient here.">