DateTimeField not shown in a template - django - django

I have two DateTime Fields in a model:
models.py
start_appointment = models.DateTimeField(default=timezone.now, blank=True)
end_appointment = models.DateTimeField(default=timezone.now, blank=True)
i also have a form where i set widgets for above fields:
'start_appointment': forms.DateTimeInput(attrs={'class': 'form-control', 'type': "datetime-local"}),
'end_appointment': forms.DateTimeInput(attrs={'class': 'form-control', 'type': "datetime-local"}),
i have an update view where i want to update appointment's fields for example start_appointment. However when rendering form in a template these two fields are shown as dd/mm/yyyy --:--, -- meaning values from database not shown, while all the others are rendered with no problem.
From the other hand i can execute the form with no problem and update is successful.
template:
<div class="form-group row">
<label class="col-form-label col-3 text-lg-right text-left">{% trans 'Start Appointment' %}</label>
<div class="col-9">
{{ form.start_appointment }}
</div>
</div>
Update
Adding forms.py
class AddAppointmentForm(forms.ModelForm):
class Meta:
model = Appointment
fields = ['user', 'name', 'appointment_notes', 'seat', 'start_appointment', 'end_appointment']
widgets = {
'user': forms.Select(attrs={'class': 'form-control'}),
'name': forms.TextInput(attrs={'class': 'form-control'}),
'appointment_notes': forms.Textarea(attrs={'maxlength': '900', 'class': 'form-control' }),
'seat': forms.Select(attrs={'class': 'form-control'}),
'start_appointment': forms.DateTimeInput(attrs={'class': 'form-control', 'type': "datetime-local"}),
'end_appointment': forms.DateTimeInput(attrs={'class': 'form-control', 'type': "datetime-local"}),
}
What might be the problem?

the problem might be this 'type': "datetime-local"
try this
try to change your datetime to something like this
'start_appointment': forms.DateTimeInput(format='%Y-%m-%d %H:%M:%S', attrs={'class':'datetimefield'})
and for datetimepicker you can use something like this
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<script>
window.addEventListener("DOMContentLoaded", function () {
flatpickr(".datetimefield", {
enableTime: true,
enableSeconds: true,
dateFormat: "Y-m-d H:i:S",
});
});
</script>
you can learn more on Flatpickr here https://flatpickr.js.org/

Related

Django Summernote icons dont appear

I am working on a MAC and Windows for this issue. Summer note will not display icons in chrome or edge on either Mac or windows and deployed or locally. Everything works fine in safari and on my iPhone. I migrated and collected the static files and they showed up in my s3 bucket. Seems like everything is set up correctly since it does work.
settings.py
INSTALLED_APPS = [
'django_summernote',
]
SUMMERNOTE_THEME = 'bs5'
SUMMERNOTE_CONFIG = {
'summernote': {
'width': '100%',
}
}
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('summernote/', include('django_summernote.urls')),
]
forms.py
from django_summernote.widgets import SummernoteWidget, SummernoteInplaceWidget
class CreateVenueForm(ModelForm):
class Meta:
model = Venue
fields = ('name', 'address', 'city', 'state', 'zip', 'description',)
widgets = {
'name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Gived your venue a title'}),
'address': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Number and Street name'}),
'city': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'city'}),
'state': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Give your event a title'}),
'zip': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Zip'}),
'description': SummernoteWidget(),
}
template
<div class="row">
<div class="col">{{form.description.label}}<br/>{{form.description|safe}}</div>
</div>

How do I change input type of form field in django forms?

I have a form class in my form.py file where I initiated properties of form fields. I want to change my 'Description' field from an input field to a textarea field of height 5 lines. Also want to change my 'Deadline' field to a date input field because at the moment it's an input text field.
class JobPost_form(ModelForm):
class Meta:
model = Job_post
fields = "__all__"
def __init__(self, *args, **kwargs):
self.fields['Job_role'].widget.attrs.update(
{'class': 'form-control Password2', 'id': 'form3Example1c', 'placeholder': 'Job role'})
self.fields['Company'].widget.attrs.update(
{'class': 'form-control', 'id': 'form3Example1c', 'placeholder': 'Company'})
self.fields['Deadline'].widget.attrs.update(
{'class': 'form-control', 'id': 'form3Example1c', 'placeholder': 'YYYY-MM-DD HH:MM:SS'})
self.fields['Description'].widget.attrs.update(
{'class': 'form-control', 'id': 'form3Example1c', 'placeholder': 'Description'})
I think that in the code you have passed a tabulation is missing since the meta and the init will be inside the class: JobPost_form. As for marking the description field as a textarea you should do:
class JobPost_form(ModelForm):
description = forms.CharField(widget=forms.TextInput(attrs={"class": "form-control"}))
class Meta:
model = Job_post
fields = "__all__"
def __init__(self, *args, **kwargs):
...
You can achieve those things using wigets(attrs="{}") which provided by django in forms api
models.py
class DemoClass(models.Model):
description = models.TextField()
deadline = models.DateField()
form.py
class DemoForm(forms.ModelForm):
class Meta:
model = DemoClass
fields = "__all__"
widgets={
'description':forms.Textarea(attrs={"rows":"4", "cols":"50"}),
'deadline':forms.TextInput(attrs={'type':'date'}),
--------------- OR -------------------------------
'deadline':forms.DateInput(attrs={'type':'date'}),
}
HTML
{% block body %}
<div class="container">
<div class="row">
<div class="col-lg-12">
{{form.as_p}}
</div>
</div>
</div>
{% endblock body %}
Output

DateTimeField not showing previous date and time when editing

I want previously set dates and times to be displayed before they are edited. The previously set name and description of my event are being displayed as it should. Here's a part of my code:
Forms:
class EventForm(forms.ModelForm):
name = forms.CharField(label='Event name', widget=forms.TextInput(attrs={'class': 'form-control'}))
description = forms.CharField(label='Description', required=False, widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4, 'cols': 15}))
date_hour_start = forms.DateTimeField(input_formats=['%d/%m/%Y %H:%M'], widget=forms.DateTimeInput(attrs={'type': 'datetime-local', 'class': 'form-control col-md-4'}))
date_hour_end = forms.DateTimeField(input_formats=['%d/%m/%Y %H:%M'], widget=forms.DateTimeInput(attrs={'type': 'datetime-local', 'class': 'form-control col-md-4'}))
Views:
def event_update_view(request, event_id):
event = get_object_or_404(Event, event_id=event_id)
event.date_hour_start = datetime.datetime.strftime(event.date_hour_start, '%d/%m/%Y %H:%M:%S')
event.date_hour_end = datetime.datetime.strftime(event.date_hour_end, '%d/%m/%Y %H:%M:%S')
if request.method == 'POST':
form = EventForm(request.POST, instance=event)
if form.is_valid():
event = form.save()
event.save()
return redirect(reverse('list_events'))
return redirect(reverse('list_events'))
def event_create_view(request):
form = EventForm(request.POST or None)
if form.is_valid():
form.save()
form = EventForm()
return redirect(reverse('list_events'))
context = {
'form': form
}
return render(request, "eventss/add_event.html", context)
HTML (just a part):
<div class="col-md-12">
<p style="margin-bottom: .5rem">Date and Time (Start) <span style="color:red">*</span></p>
{{ form.date_hour_start }}
</div>
<div class="col-md-12">
<p style="margin-bottom: .5rem">Date and Time (End)<span style="color:red">*</span></p>
{{ form.date_hour_end }}
</div>
Why isn't it working? Here's how it's showing. (It's aaaa because it's in Portuguese but it's the year)
To get the instance date and time to show in the datetime-locale input, please change the form input using widgets to the following:
widgets = {
'start_date': forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}, format='%Y-%m-%dT%H:%M'),
'end_date': forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}, format='%Y-%m-%dT%H:%M'),
}

Required field error happans only when using ajax

I have a model named SaleEntry:
class SaleEntry(models.Model):
date = models.DateField()
ebay_price = models.FloatField()
amazon_price = models.FloatField()
ebay_tax = models.FloatField()
paypal_tax = models.FloatField()
tm_fee = models.FloatField(default=0.3)
promoted = models.FloatField(default=0.0)
profit = models.FloatField()
discount = models.FloatField(default=0)
country = models.CharField(max_length=100, default="-----")
user = models.ForeignKey(User, on_delete=models.CASCADE, default=0)
def save(self, *args, **kwargs):
if not self.pk: # object is being created, thus no primary key field yet
change_balance = Balance.objects.get(user=self.user)
change_balance.balance = change_balance.balance - self.amazon_price - self.tm_fee + self.discount
change_balance.save()
super(SaleEntry, self).save(*args, **kwargs)
def calc_profit(self):
return self.ebay_price - self.amazon_price - self.ebay_tax - self.paypal_tax - self.tm_fee - self.promoted + self.discount
def __str__(self):
return f'{self.user} - {self.profit}'
And I have a form handling this model SaleEntryForm:
class SaleEntryForm(ModelForm):
class Meta:
model = SaleEntry
fields = "__all__"
widgets = {
'date': DateInput(attrs={'class': 'form-control', 'id':'f_date'}),
'ebay_price': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': 'eBay Price', 'id':'f_ebay_price', 'onkeyup': 'calc_profit()'}),
'amazon_price': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': 'Amazon Price', 'id':'f_amazon_price', 'onkeyup': 'calc_profit()'}),
'ebay_tax': forms.NumberInput(attrs={'class': 'form-control col-1', 'placeholder': 'eBay Tax', 'id':'f_ebay_tax', 'onkeyup': 'calc_profit()'}),
'paypal_tax': forms.NumberInput(attrs={'class': 'form-control col-1', 'placeholder': 'Paypal Tax', 'id':'f_paypal_tax', 'onkeyup': 'calc_profit()'}),
'tm_fee': forms.NumberInput(attrs={'class': 'form-control col-1', 'placeholder': 'TM Fee', 'id':'f_tm_fee', 'onkeyup': 'calc_profit()'}),
'promoted': forms.NumberInput(attrs={'class': 'form-control col-1', 'placeholder': 'Promoted', 'id':'f_promoted', 'onkeyup': 'calc_profit()'}),
'profit': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': 'Profit', 'readonly':'true', 'id':'f_profit'}),
'discount': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': 'Discount', 'id':'f_discount'}),
'country': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Country', 'id':'f_country'}),
}
def __init__(self, *args, **kwargs):
'''
relate the sale registration form to the user who created it.
'''
user_id = kwargs.pop('user_id')
super().__init__(*args, **kwargs)
self.fields['user'] = forms.ModelChoiceField(queryset=User.objects.filter(id=user_id), empty_label=None, initial=User.objects.get(id=user_id))
self.fields['user'].widget.attrs['class'] = 'no-display'
I am using this form in the html page:
<form id="form_add_sale">
{% csrf_token %}
<tr>
{% for field in form %}
{% if field is not form.user %}
<td>
{{ field }}
</td>
{% else %}
{{ field }}
{% endif %}
{% endfor %}
<td><input class="btn btn-primary" type="submit" display="inline" name="btn_register_sale"></td>
</tr>
</form>
and this is the ajax to send the data to server:
$(document).on("submit", '#form_add_sale', function(e){
e.preventDefault();
$.ajax({
url:"{% url 'add_sale' %}",
type:"POST",
data:{
date: $("#f_date").val(),
ebay_price: $("#f_ebay_price").val(),
amazon_price: $("#f_amazon_price").val(),
ebay_tax: $("#f_ebay_tax").val(),
paypal_tax: $("#f_paypal_tax").val(),
tm_fee: $("#f_tm_fee").val(),
promoted: $("#f_promoted").val(),
profit: $("#f_profit").val(),
discount: $("#f_discount").val(),
country: $("#f_country").val(),
},
success: function(){
alert("Created new sale!");
}
})
//.done(function(response){
// $("#table_sales").load(location.href + " #table_sales");
//})
.fail(function(xhr, status, error){
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
})
})
upon submitting the form, I'm getting the next error (which didn't occur when submitting the form regularly without ajax with the exact same code in the view):
<ul class="errorlist"><li>user<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
this is the request.POST:
<QueryDict: {'date': ['2021-02-11'], 'ebay_price': ['70'], 'amazon_price': ['50'], 'ebay_tax': ['10'], 'paypal_tax': ['5'], 'tm_fee': ['0.3'], 'promoted': ['0.0'], 'profit': ['4.70'], 'discount': ['0'], 'country': ['-----']}>
I think you forgot the csrf_token. try adding:
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
to the data.
More information can be found here

django ImageField empty after form post

When I upload a photo to django through form the image field is empty. I confirmed this by using logging.info(form.cleaned_data['picture'] )
I checked through the console that the form has 'multipart/form-data'
The model :
class Person(models.Model):
user = models.ForeignKey(User, default=1)
name = models.CharField(max_length=250,null=True)
last_name = models.CharField(max_length=500)
treatment_plan=models.CharField(max_length=256,null=True,blank=True)
treatment_done=models.CharField(max_length=256,null=True,blank=True)
picture = models.ImageField(upload_to='image', storage=DEFAULT_FILE_STORAGE,blank=True)
def __str__(self):
return self.name
the modelForm :
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = ['name', 'last_name', 'age', 'martial_status', 'mobile', 'sex',
'amount_paid','amount_left','note', 'address','date','picture','treatment_done','treatment_plan','chief_complain']
widgets = {
'name': forms.TextInput(attrs={'required': True, 'class': 'form-control',
'placeholder': 'name'}),
'last_name': forms.TextInput(attrs={'required': True, 'class': 'form-control',
'picture': forms.FileInput(attrs={'required': False,'class': 'form-control','enctype': 'multipart/form-data'}),
view.py :
def add_person(request):
if not request.user.is_authenticated():
return render(request, 'core/login.html')
else:
form = PersonForm(request.POST or None,request.FILES or None,instance=Person())
#form = PersonForm(request.POST or None,request.FILES )
if form.is_valid():
persons = form.save()
persons.user = request.user
#to capitalized the first letter so we have consistency when querying , this is a workaround since __iexact is not working
persons.name=persons.name.title()
persons.last_name=persons.last_name.title()
logging.info(form.cleaned_data['last_name'] )
persons.save()
return redirect('home')
context = {
"form": form,
}
return render(request, 'core/add_person.html', context)
The html template :
<div class="col-sm-4 form-group">
<label for="address">{% trans "Address" %}</label>
{{ form.address|add_class:"form-control" }}
</div>
<div class="col-sm-4 form-group">
<label for="pic">{% trans "Picture" %}</label>
{{form.picture}}
</div>
I may be wrong, but still, as far as I know the parameter "multipart/form-data" should be in the form, and not in input, and you install it to the FieldFile
'picture': forms.FileInput(attrs={'required': False,'class': 'form-control','enctype': 'multipart/form-data'}),