What I can't see input datetime form.form django in my browser?
the program that I run in the browser,
The following code displayed instead of the input datetime
i have brought the codes of all the pages, please check
Thank you for your reply
forms.py
from django import forms
from django.contrib.auth.models import User
from datetime import datetime
class ExpenseForm (forms.Form):
text = forms.CharField(
widget=forms.TextInput(attrs={'placeholder':'توضیحات' ,'class':'form-control'}),
label='توضیحات',
)
date = forms.DateTimeField(
initial=datetime.now(),
widget=forms.DateTimeInput(attrs={ 'placeholder':'تاریخ' ,
'class':'form-control',
'type': 'datetime-local'}),
label='تاریخ',
)
amount = forms.IntegerField(
widget=forms.NumberInput(attrs={'placeholder':'مقدار' ,'class':'form-control'}),
label='مقدار'
)
view.py
#login_required()
def submit_expense(request):
expense_form = ExpenseForm(request.POST or None)
if expense_form.is_valid():
text = expense_form.cleaned_data.get('text')
date = expense_form.cleaned_data.get('date')
amount = expense_form.cleaned_data.get('amount')
Expense.objects.create(text=text , date=date , amount=amount , user_id=request.user.id)
return redirect('/submit/expense')
context ={
'expense_form':expense_form
}
return render(request,'hello.html',context)
hello.html
{% extends 'shared/_MainLayout.html' %}
{% load static %}
{% block content %}
<div class="login-form"><!--expense form-->
<div class="col-sm-4 col-sm-offset-1">
<div class="login-form"><!--expense form-->
<h2>پولهای خرج شده :</h2>
<form method="post" action="#">
{% csrf_token %}
{{ expense_form.text }}
{{ expense_form.amount }}
{{ expense_form.data }}
<button type="submit" class="btn btn-default">ثبت</button>
</form>
</div><!--/login form-->
</div>
{% endblock %}
please check the image to see my problem
browser page
you wrote {{ expense_form.data }} instead of {{ expense_form.date }}
Related
I'm trying to create a frontend data entry page for an existing model. However, when clicking the link, I get an error:
crispy_forms.exceptions.CrispyError: |as_crispy_field got passed an invalid or inexistent field
Just to be clear, adding the data from Django Admin works with no issues at all.
Having looked through a number of answered questions here, one did highlight what I believe could be problem, but it was out of context and did not provide much of an explanation.
I am trying to create a frontend entry form for users that corresponds with a foreign key.
models.py
class NewHandoff(models.Model):
handoff_pk = models.AutoField(primary_key=True)
handoff_date = models.DateField(auto_now_add=True,verbose_name="Handoff Date")
shift1_pri = models.ForeignKey(Engineer,on_delete=models.CASCADE,verbose_name="Shift 1 Primary")
shift1_sec = models.ForeignKey(Engineer,on_delete=models.CASCADE,verbose_name="Shift 1 Secondary")
def __str__(self):
return f"{self.handoff_date}"
class Meta:
verbose_name_plural = 'Handoffs'
# New Handoff Form
class NewHandoffForm(forms.ModelForm):
class Meta:
model = NewHandoff
fields = ['shift1_pri','shift1_sec']
views.py
from django.shortcuts import redirect, render
from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http.response import HttpResponse
from django.contrib import messages
from .models import AttentionForm, NewHandoffForm
# Handoff View Page
class NewHandoffView(LoginRequiredMixin,View):
def get(self, request):
greeting = {}
greeting['heading'] = "New Handoff"
greeting['pageview'] = "Handoff"
return render (request,'handoff/handoff-new.html')
def post(self, request):
if request.method == "POST":
if "add-new-handoff-button" in request.POST:
create_new_handoff_form = NewHandoffForm(request.POST)
create_new_handoff_form.save()
return redirect("/handoff/handoff-create")
handoff-new.html
{% extends 'partials/base.html' %}
{% load static %}
{% load humanize %}
{% load crispy_forms_tags %}
{% block extra_css %}
<link href="{% static 'libs/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css' %}" rel="stylesheet">
{% endblock %}
{% block contents %}
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<!-- New Form -->
<form method="POST">
{% csrf_token %}
<div class="row">
<div class="row-fluid pb-1">
<!-- Field 1 -->
<div class="mb-3">
{{ form.shift1_pri|as_crispy_field }}
</div>
<!-- End of Field 1 -->
</div>
</div>
<div class="d-flex flex-wrap gap-2">
<button type="submit" class="btn btn-primary waves-effect waves-light" name="add-new-handoff-button">Create New Handoff</button>
</div>
</form>
<!-- End of New Form -->
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_javascript %}
{% endblock %}
Someone mentioned in another post that forms should correlate with the declared form name {{ form.shift1_mod|as_crispy_field }} so it should actually be {{ create_new_handoff_form.shift1_mod|as_crispy_field }} but I have tried changing this and still get the same problem, plus, another model form works fine with just form despite the name of the form being attention_form.
Does anyone have any idea or can point me in the right direction? :)
You are not passing the form through the context in the template. As you are inheriting View, Add the following line in the get() and afterwards in the post() method appropriately:
form = NewHandoffForm()
# and then change return
return render(request,'handoff/handoff-new.html', {'form': form })
Also, you have a space after render in the get function. I hope this is a typo here, but not in your code.
I have a models.py with the following fields:
class ChatStream(models.Model):
bot = models.TextField()
user = models.TextField()
name = models.CharField(max_length=100, null=True)
created_date = models.DateTimeField(auto_now_add=True)
And I'd like on a website to iterate through "bot" and "user" one at a time, so the site would hypothetically display something like:
bot: hello!
user: what's up?
bot: I'm good
user: What's your name
bot: bot is my name
.... etc. this would keep going...
So in my views.py I have
def displayDict(request):
m = ChatStream.objects.all()
return render(request, 'chatStream.html',
{"chat": m})
def send(request):
message = request.POST.get('userMessage', False)
ip = visitor_ip_address(request)
response = routes(message, ip)
print(ip, "user sent:", message, "bot response:", response)
chatItem = ChatStream(bot=response, user=message, name=ip)
chatItem.save()
return HttpResponseRedirect('/chat/')
Then in my template, chat.html I have
{% block chatStream %} {% endblock %}
And chatStream.html (this is where the error is happening I believe... how do you iterate through two items in the model so they appear one after the other on the html file?)
{% extends 'chat.html' %}
{% block chatStream %}
{% for a in bot%}
{% for b in user%}
<p>
<b>bot:</b> {{a}} <br>
<b>user:</b> {{b}} <br>
</p>
{% endfor %}
<form action="/send/" method = "post">{% csrf_token %}
<input type="text" name="userMessage">
<input type="submit" value="Send to smallest_steps bot">
</form>
{% endblock %}
But this does not work -- no text from the model is displayed on the site. I am not understanding how to iterate through two items within the model at once inside of the chatStream.html.
A lot going on here, lets try to break it down:
First, you need to pass context variables to your templates if you want to render them using the (jinja-like) Django template rendering system.
Your view function for rendering the template would look like this:
views.py
def render_chat_page(request):
# do some logic:
...
# pack the context variables:
context = {
'some_key' : 'some_value',
'chat_streams' : ChatStream.objects.all(),
...
}
return render(request, 'chat_page.html', context=context)
Ok, now that we've passed the context variables to the template, we can render html elements using the variables like so:
template.html
<div> The value of "some_key" is: {{some_key}} </div>
{% for chat_stream in chat_streams %}
<div> user says: {{chat_stream.user}}</div>
<div> bot says: {{chat_stream.bot}}</div>
{% endfor %}
This will render the user and bot messages for each ChatStream object. However my hunch is that this is not entirely what you're after, instead you may want something more dynamic.
In your displayDict view you're passing a QuerySet to the context. So, you need to loop over the QuerySet in your template.
{% extends 'chat.html' %}
{% block chatStream %}
{% for item in chat %}
<p>
<b>bot:</b> {{item.bot}} <br>
<b>user:</b> {{item.user}} <br>
</p>
{% endfor %}
<form action="/send/" method = "post">{% csrf_token %}
<input type="text" name="userMessage">
<input type="submit" value="Send to smallest_steps bot">
</form>
{% endblock %}
So I am currently working on the project in Django. The user should be able to set start date and the end date, based on this set interval an analysis should be calculated.
The current problem is, when the data comes to validation, it sees input data as an NoneType.
Note: I did not upload the entire html code. Only form relevant code.
forms.py
from django import forms
from tempus_dominus.widgets import DatePicker
import datetime
class AnalysisInformationForm(forms.Form):
start = forms.DateField(help_text="Enter a date between 2019-03-01 and now.",
input_formats=["%d/%m/%Y"],
widget=DatePicker(
options={
'minDate': '2019-03-01',
'maxDate': datetime.datetime.utcnow().date().strftime("%Y-%m-%d")
})
)
end = forms.DateField(help_text="Enter a date between the chosen start date and now",
input_formats=["%d/%m/%Y"],
widget=DatePicker(
options={
'minDate': '2019-03-01',
'maxDate': datetime.datetime.utcnow().date().strftime("%Y-%m-%d")
})
)
def clean(self):
cleaned_data = super(AnalysisInformationForm, self).clean()
start = cleaned_data.get('start')
end = cleaned_data.get('end')
print(start, end)
if start >= end:
raise forms.ValidationError('Invalid dates input. The start day must be set earlier than the end date. ')
return cleaned_data
views.py
def index(request):
if request.method == 'POST':
form = AnalysisInformationForm(request.POST)
if form.is_valid():
pass
else:
form = AnalysisInformationForm()
return render(request, 'stm/index.html', {'form': form})
index.html
<head>
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css">
<link rel="stylesheet" href="{% static 'css/bootstrap.css' %}"><link>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
</head>
{{ form.media }}
<body>
<div class="form-group"></div>
{% load widget_tweaks %}
<form method="post" novalidate>
{% csrf_token %}
{% for hidden_field in form.hidden_fields %}
{{ hidden_field }}
{% endfor %}
{% if form.non_field_errors %}
<div class="alert alert-danger" role="alert">
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% for field in form.visible_fields %}
<div class="input-group">
{{ field.label_tag }}
{% if form.is_bound %}
{% if field.errors %}
{% render_field field class="form-control is-invalid" %}
{% for error in field.errors %}
<div class="invalid-feedback">
{{ error }}
</div>
{% endfor %}
{% else %}
{% render_field field class="form-control is-valid" %}
{% endif %}
{% else %}
{% render_field field class="form-control" %}
{% endif %}
{% if field.help_text %}
<small class="form-text text-muted">{{ field.help_text }}</small>
{% endif %}
</div>
{% endfor %}
<div class="input-group m-3">
<input type="submit" class="btn btn-outline-secondary btn-block" value="Continue">
</div>
</form>
</body>
These tutorials brought me to this solution:
https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html#rendering-bootstrap-4-forms
https://pypi.org/project/django-tempus-dominus/
https://pypi.org/project/django-widget-tweaks/
I also found a similar question on stack overflow, though no answer:
Django DateField form generates None in cleaned_data
I also tried to do the following to check whether the actual data is coming through.
so in views.py I've changed the following:
Before:
form = AnalysisInformationForm(request.POST)
After:
form = request.POST['start']
print(form)
In between the Errors I found that print statement. And surprise, surprise, the given start date did match the actual input.
But after the data has been cleaned it becomes a NoneType value.
Any suggestions what might be the cause?
The expected result is for the data to be able to get validated as shown in the code. The start date must be set earlier than the end date and if not show the error message.
So after trying several things. I've come to the following solution:
Firstly in forms.py I've updated the clean function to match the following. Found this clean function somewhere here on stackoverflow, but forgot to save the link to it, didn't know if this would work:
def clean(self):
data = self.cleaned_data
print(data)
start = data.get('start')
end = data.get('end')
if start >= end:
raise forms.ValidationError('Invalid dates input. The start day must be set earlier than the end date. ')
return data
Then I tried several date input formats, such as ["%y/%m/%d"](19/04/02 format, not iso), ["%Y/%m/%d"](2019/04/02 format, not iso), ["%y-%m-%d"](19-04-02 format, not iso), ["%Y-%m-%dT%H:%M:%S.%fZ"](well, iso datetime format, but I'm working with date objects not datetime objects). So I've come to conclusion that I just have to change the / to - in ["%Y/%m/%d"] and everything should work. And it actually did work :D
This is how the new updated form class looks like:
class AnalysisInformationForm(forms.Form):
start = forms.DateField(help_text="Enter a date between 2019-03-01 and now.",
input_formats=["%Y-%m-%d"],
widget=DatePicker(
options={
'minDate': '2019-03-01',
'maxDate': datetime.datetime.utcnow().date().strftime("%Y-%m-%d")
})
)
end = forms.DateField(help_text="Enter a date between the chosen start date and now",
input_formats=["%Y-%m-%d"],
widget=DatePicker(
options={
'minDate': '2019-03-01',
'maxDate': datetime.datetime.utcnow().date().strftime("%Y-%m-%d")
})
)
Thanks to everyone who tried to help, you helped me find the right solution.
may be you need to make " post " in html all uppercase
<form method="POST" novalidate>
Try to find what passed to the clean() method before the super() is called. Perhaps it comes from client in non-iso format and did not pass the default validation from superclass
for django 2.1 try this
def clean(self):
cleaned_data = super().clean()
start = cleaned_data.get("start")
end = cleaned_data.get("end")
hope it helps
I wanted to add the "search" functionality to my model, but the [querystring][1] doesn't seem to work as I expected it to. Here's my attempt:
from django.db import models
class ProductsByOneDayMax(models.Model):
product = models.TextField(max_length=65535, verbose_name="Product name")
max = models.IntegerField(verbose_name="Max daily IPs")
class Meta:
db_table = 'precomputed_product_distinct_ip_one_day_max'
from django.db import connection as conn
from django.shortcuts import render
from viewer.models import ProductsByOneDayMax
import django_tables2 as tables
def list_products(request):
class ProductsByOneDayMaxTable(tables.Table):
class Meta:
model = ProductsByOneDayMax
exclude = ('id', )
search = request.GET.get('search', '')
objects = ProductsByOneDayMax.objects.filter(product__icontains=search)
table = ProductsByOneDayMaxTable(objects)
table.order_by = "-max"
tables.RequestConfig(request).configure(table)
return render(request, "plain_table.html", {'table': table,
'title': 'Product list',
'search': search})
And the view:
{% extends "base.html" %}
{% block content %}
{% load django_tables2 %}
{% querystring "search"=search %}
<form class="form-inline" method="get" role="form">
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-search"></span></span>
<input type="text" class="form-control " value="" placeholder="Search..." name="search">
</div>
<button type="submit" class="btn btn-primary">Search</button>
</form>
{% render_table table %}
{% endblock %}
Instead of adding the "search" field to the querystring, this only gets added to the output. What am I doing wrong?
In case it's relevant, I am using bootstrap-tables2.css.
Looks like this was solved in the last GitHub comment for the linked template:
The bootstrap_pagination tag needs the full URL in order to properly
sort columns between pages:
{% bootstrap_pagination table.page url=request.get_full_path %}
This
assumes you have "django.core.context_processors.request" in
settings.TEMPLATE_CONTEXT_PROCESSORS
Modifying the template solved the problem.
I wrote a simple app that is a custom DateField widget for mezzanine. Afaik it's, it's a simple case and besides overextending a template it would be the same in pure django or django-cms (feel free to correct me if I'm wrong).
The widget:
class DatePickerInput(forms.DateInput):
def __init__(self, attrs = None, format = None):
super(DatePickerInput, self).__init__(attrs, format)
self.attrs["class"] = "datepicker"
class Media:
css = { "all": ('css/ui-lightness/jquery-ui-1.10.3.custom.min.css',) }
js = (
"mezzanine/js/" + getattr(settings, "JQUERY_UI_FILENAME", "jquery-ui-1.9.1.custom.min.js"),
"js/datepicker_setup.js",)
I overextend base.html template to insert form.media:
{% overextends "base.html" %}
{% load pages_tags mezzanine_tags i18n future staticfiles %}
{% block extra_head %}{{ block.super }}
{{ form.media }}
{% endblock %}
Now, I create a form for my model class.
Here's the class:
class PlayerProfile(models.Model):
user = models.OneToOneField("auth.User")
# Can be later changed to use a setting variable instead of a fixed date
date_of_birth = models.DateField(default=date(1990, 1, 1))
Here's the model form:
from DateWidgets.widgets import DatePickerInput
from PlayerProfiles.models import PlayerProfile
class EditPlayerProfileForm(Html5Mixin, forms.ModelForm):
class Meta:
model = PlayerProfile
fields = ("date_of_birth", )
widgets = { 'date_of_birth': DatePickerInput }
def __init__(self, *args, **kwargs):
super(EditPlayerProfileForm, self).__init__(*args, **kwargs)
Here's the view:
#login_required
def profile_update(request, template="accounts/account_profile_update.html"):
"""
Profile update form.
"""
pform = forms.EditPlayerProfileForm
player_form = pform(request.POST or None, request.FILES or None, instance=request.user.playerprofile)
context = {"pform": player_form, "title": _("Update Profile"), "profile_user": request.user}
return render(request, template, context)
Here's the template:
{% overextends "accounts/account_profile_update.html" %}
{% load i18n mezzanine_tags %}
{% block main %}
<fieldset>
<legend>{{ title }}</legend>
<form method="post"{% if pform.is_multipart %} enctype="multipart/form-data"{% endif %}>
{% fields_for pform %}
<div class="form-actions">
<input class="btn btn-primary btn-large" type="submit" value="{{ title }}">
</div>
</form>
</fieldset>
{% endblock %}
Now if I view the form in a browser, the custom widget is there (I can tell because the input html tag has my custom class attribute value) but it doesn't inject the form media, it's missing. Any idea what's going on here? Thanks in advance! Cheers :-)
form isn't available in the template, because you've called your form variable pform.
Try {{ pform.media }}.
I was googled here with the same problem under different conditions and spotted another error that may appear under other conditions (my case is extending change_form.html in Django 2.1): I had to use extrahead instead of extra_head
{% block extrahead %}{{ block.super }}
{{ form.media }}
{% endblock %}