Django DateTimeField not showing up properly in browser - python

I want my django DateTimeField to be inputted the same way I input the values from the admin page, where the dates are selected from a calender.
for reference this is how my models.py look like:
from django.db import models
# Create your models here.
class TheDate(models.Model):
"""A topic the user is learning about"""
theDate = models.DateTimeField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
"""returns a string representation of the model"""
return str(self.theDate)
forms.py
class NewDate(forms.ModelForm):
class Meta:
model = TheDate
fields = ['theDate']
labels = {'theDate': ''}
the html page where i have set to create a new plan- new_date.html:
{% extends "meal_plans/base.html" %}
{% block content %}
<p>Add new Date:</p>
<form action="{% url 'meal_plans:new_date' %}">
{% csrf_token %}
{{ form.as_p }}
<button name="submit">Add New Date</button>
</form>
{% endblock content %}
what can i do to the data be inputted in that way
i hope the code here is enough and relevant.

Hello I had similar problem and I found something like this
class DateInput(forms.DateInput):
input_type = 'date'
And then in your modelform
class NewDate(forms.ModelForm):
class Meta:
model = TheDate
widgets = {
'theDate': DateInput()
}
fields = ['theDate']

Put in your forms.py something like this:
class NewDate(forms.ModelForm):
theDate = forms.DateTimeField (
widget=forms.DateTimeInput (
attrs={
'type': 'datetime-local',
}
)
)
class Meta:
model = TheDate
fields = ['theDate']
labels = {'theDate': ''}
This worked here!

Related

Django form with dropdown list using Database returns empty fields

I'm discovering Django and I'm trying to develop a simple application.
I have three tables in my database :
One big table to report all the information to users and 2 tables to create drop down list on my form (but no usage of foreign keys on purpose). I need to have these two tables because statuses and areas need to be editable at all time and need to be written in the same way each time in the main table Action.
Here is my model.py :
class Status(models.Model):
id_status = models.AutoField(db_column='ID_STATUS', primary_key=True)
status = models.CharField(db_column='STATUS', max_length=50)
def __str__(self):
return self.status
class Meta:
managed = False
db_table = 'T_EAVP_STATUS'
class Area(models.Model):
id_area = models.AutoField(db_column='ID_AREA', primary_key=True)
area_name = models.CharField(db_column='AREA_NAME', max_length=50)
def __str__(self):
return self.area_name
class Meta:
managed = False
db_table = 'T_EAVP_AREA'
class Action(models.Model):
id = models.AutoField(db_column='ID', primary_key=True)
title = models.CharField(db_column='TITLE', max_length=200)
due_date = models.DateTimeField(db_column='DUE_DATE')
status = models.CharField(db_column='STATUS', max_length=50)
date_insert = models.DateTimeField(db_column='DATE_INSERT', auto_now_add=True)
emitting_area = models.CharField(db_column='EMITTING_AREA', max_length=50)
receiving_area = models.CharField(db_column='RECEIVING_AREA', max_length=50)
owner = models.CharField(db_column='OWNER', max_length=200)
def __str__(self):
return self.title
class Meta:
managed = False
db_table = 'T_EAVP_ACTION'
Here is my forms.py :
class ActionForm(forms.ModelForm):
status = forms.ModelChoiceField(queryset=Status.objects.all())
receiving_area = forms.ModelChoiceField(queryset=Area.objects.all())
emitting_area = forms.ModelChoiceField(queryset=Area.objects.all())
class Meta:
model = Action
fields = ['title', 'due_date', 'owner']
Here is my views.py :
#csrf_exempt
#xframe_options_exempt
def action_add(request):
if request.method == 'POST':
form = ActionForm(request.POST)
if form.is_valid():
action = form.save()
return redirect('action-list')
else:
form = ActionForm()
return render(request, 'polls/action_add.html', {'form': form})
Here is my HTML code :
{% extends 'polls/base.html' %}
{% block title %}{{ action.title }}{% endblock %}
{% block content %}
<h1>Ajouter une action</h1>
<form action="" method="post" class="form" novalidation>
{% csrf_token %}
{{ form }}
<br><br>
<input type="submit" class="submit" value="Créer">
</form>
{% endblock %}
I'm pretty sure I've imported all the needed libraries from Django.
Problem : When I'm running my code and I try to create a new action using my ActionForm, it is not working properly.
In the Action table, the fields that correspond to the fields filled by the drop down lists are completely empty.
Table Status and table Area contain values so the problem is not coming from here.
I've tried a lot of different things but nothing seems to work and fields are always empty in my database after the save of the form.
If someone sees a solution, I'm interested !
The solution was to add the name of the fields in form.py :
class ActionForm(forms.ModelForm): # Crée un formulaire se basant sur Action
status = forms.ModelChoiceField(queryset=Status.objects.all())
receiving_area = forms.ModelChoiceField(queryset=Area.objects.all())
emitting_area = forms.ModelChoiceField(queryset=Area.objects.all())
class Meta:
model = Action
fields = ['title', 'due_date', 'owner', 'status', 'receiving_area', 'emitting_area']
Thank you Willem Van Onsem !

How to render information from a ForeignKey field through DetailView class?

I have two models (Taxonomia and Distribucion) which are the following:
# models.py file
class Taxonomia(models.Model):
id_cactacea = models.AutoField(primary_key=True)
subfamilia = models.CharField(max_length=200)
class Distribucion(models.Model):
id_distribucion = models.AutoField(primary_key=True)
localidad = models.TextField(null=True, blank=True)
taxonomia = models.ForeignKey(Taxonomia, on_delete=models.CASCADE, default=1)
As you can see in Distribucion there is a one to many relationship with the Taxomia table.
Implement the two models in the "admin.py" file so that you can edit the Distribucion table from Taxonomia
class DistribucionInline(admin.TabularInline):
model = Distribucion
extra = 0
class TaxonomiaAdmin(admin.ModelAdmin):
actions = None # desactivando accion de 'eliminar'
list_per_page = 20
search_fields = ('genero',)
radio_fields = {"estado_conservacion": admin.HORIZONTAL}
inlines = [DistribucionInline]
admin.site.register(Taxonomia, TaxonomiaAdmin)
In turn, the file "view.py" renders the Taxonomia table as follows:
from repositorio.models import Taxonomia, Distribucion
class CactaceaDetail(DetailView):
model = Taxonomia
template_name = 'repositorio/cactacea_detail.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['distribuciones'] = Distribucion.objects.all()
return context
I tried to access to context ['distribuciones'] information from the template as follows without getting any results:
{% for obj in object.distribuciones %}
{{ obj.localidad }}
{% endfor %}
OBS: For each Taxonomia element there will be four elements from the Distribucion table, so I need to use a FOR loop
Is the way I add the information from the Taxonomia table in the "CactaceaDetail" view correct?
Is the way I read the information in the template correct?
How could I visualize all the information that "CactaceaDetail" sends to the template using the DJANGO shell so that I can debug better in the future?
Thank you.
Try removing the "object" from your for loop in the template:
{% for obj in distribuciones %}
{{ obj.localidad }}
{% endfor %}
The reason is because you are passing distribuciones in the regular context, not as part of the class object so you can't reference it with object.distribuciones.

Django foreign key select field empty

I've been working on a small django website as I learn django. According to the documentation when you create a form class with a meta class that points at a model with foreign key fields, it'll render those fields as select inputs.
In my application I have 3 models, client test, and record where record carries two foreign keys, each of whom point to client and test respectively
Models.py
class Client(models.Model):
first = models.CharField(max_length=264)
last = models.CharField(max_length=264)
DOB = models.DateField()
def __str__(self):
return self.first + " " + self.last
class Test(models.Model):
test = models.CharField(max_length=264)
fee = models.DecimalField(max_digits=12, decimal_places=2)
def __str__(self):
return self.test
class Record(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
test = models.ForeignKey(Test, on_delete=models.CASCADE)
date = models.DateField()
def __str__(self):
return str(self.date) + " " + str(self.test) + " for " + str(self.client)
Form.py
class NewLabRecord(forms.ModelForm):
client = forms.ChoiceField(
label='Client ID',
widget=forms.Select(
attrs={'class': 'form-control'}))
test = forms.ChoiceField(
label='Test ID',
widget=forms.Select(
attrs={'class': 'form-control'}))
date = forms.DateField(
label='Test Date',
widget=forms.DateInput(
attrs={'class': 'form-control'}))
class Meta:
model = models.Record
fields = '__all__'
I render NewLabRecord at the top of my index view for records. The idea is to create a record and redirect back to the page (therefore seeing it in the list of records). Presently, I'm emulating class-based-views and not actually implementing it because I have not learned it yet. Nevertheless, this pattern does work for my client and test (the code is nearly identical).
Views.py
class LabRecord:
#staticmethod
def index(request):
new_record_form = forms.NewLabRecord
records = models.Record.objects.order_by('date')
print(records)
context = {
'records': records,
'new_record_form': new_record_form
}
return render(request, "layouts/lab/record/index.html", context=context)
layouts/lab/record/index.html
<div class="collapse" id="createLabRecord">
{% include 'components/lab/record/create.html' %}
</div>
components/lab/record/create.html
<!DOCTYPE html>
{% block content %}
<div class="card col-sm" style="">
<form class="form" method="post" action="{% url 'lab:create lab record' %}">
{{ new_record_form }}
{% csrf_token %}
<input type="submit" value="submit">
</form>
</div>
{% endblock %}
Now, when I go to the url for this view, /lab/records/, the view renders two select fields and an input for the date; however, the select fields are empty!
Note: I have 9 clients and 4 tests in the database!
Why is the view generating empty select fields for the foreign key fields?
In your view, you need to query your Client and Test models and put those lists into your context to make them available to your form/template.
records = models.Record.objects.order_by('date')
clients = models.Client.objects.all()
tests = models.Test.objects.all()
context = {
'records': records,
'new_record_form': new_record_form,
'clients' : clients,
'tests' : tests,
}
I have not learned the forms portion of django yet to tell you if there is something else to connect the lists to the input select fields.
Edit:
It looks like the following in your form should accomplish the desired:
class NewLabRecord(forms.ModelForm):
client = forms.ModelChoiceField(models.Client.objects.all())
test = forms.ModelChoiceField(models.Test.objects.all())
date = forms.DateField(
label='Test Date',
widget=forms.DateInput(
attrs={'class': 'form-control'}))
class Meta:
model = models.Record
fields = '__all__'
And I don't think that the changes to your view are then necessary.

Django Form Field validation

I have a form that requires a URL as input. I would like to check if the URL begins with http:// or https://.
If it doesn't have one of these two 'stings' in the beginning, the form submission should give an error.
I don't have any clue on how to get started with this and could not find any info based on my limited knowledge of django and I have no clue what search terms to look up.
A basic hint would be a great help.
Thanks!
My current forms.py has a form based on a model:
class AddUrlForm(forms.ModelForm):
class Meta:
model = forwards
# fields = '__all__'
exclude = ["user", "counterA", "counterB", "shortcodeurl", "uniqueid"]
models.py:
class forwards(models.Model):
uniqueid = models.AutoField(primary_key=True)
user = models.CharField(max_length = 150)
urlA = models.CharField(verbose_name="URL Version A", max_length = 254)
counterA = models.DecimalField( max_digits=19, decimal_places=0,default=Decimal('0'))
urlB = models.CharField(verbose_name="URL Version B",max_length = 254)
counterB = models.DecimalField( max_digits=19, decimal_places=0,default=Decimal('0'))
timestamp = models.DateTimeField('date created', auto_now_add=True)
shortcodeurl = models.CharField(max_length = 254)
html segment where that shows how the form is integrated:
<form method="post">
{% csrf_token %}
{% for field in forwardform %}
<span>{{ field.label_tag }} </span>
<p style="color: black">{{ field }} </p>
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
{% endfor %}
<button class="btn btn-outline btn-xl type="submit">Generate URL</button>
</form>
views.py:
def forwardthis(request):
forwardform = AddUrlForm(request.POST or None)
if forwardform.is_valid():
forward = forwardform.save(commit=False)
forward.user = request.user.username
forward = forwardform.save()
uniqueid_local = forward.uniqueid
uniqueid_local_bytes = uniqueid_local.to_bytes((uniqueid_local.bit_length() + 7) // 8, byteorder='little')
shortcodeurl_local = urlsafe_base64_encode(uniqueid_local_bytes)
forward.shortcodeurl = shortcodeurl_local
forward.save()
return HttpResponseRedirect('/forwardthis')
query_results = forwards.objects.filter(user=request.user.username)
query_results_qty = query_results.count()
click_results = clickstats.objects.filter(user=request.user.username)
template = loader.get_template('forwardthis.html')
context = {
'forwardform': forwardform ,
'query_results':query_results,
'query_results_qty': query_results_qty
}
return HttpResponse(template.render(context,request))
You can create a validation method for each form field. def clean_FIELDNAME(). I supose the url field is shortcodeurl:
class AddUrlForm(forms.ModelForm):
def clean_shortcodeurl(self):
cleaned_data = self.clean()
url = cleaned_data.get('shortcodeurl')
if not is_valid_url(url): # You create this function
self.add_error('shortcodeurl', "The url is not valid")
return url
class Meta:
model = forwards
# fields = '__all__'
exclude = ["user", "counterA", "counterB", "shortcodeurl", "uniqueid"]
For anyone coming here in 2021.
Nowadays Django provides the tools to achieve this kind of validation.
Based on Django 3.2 documentation
from django import forms
from django.core.exceptions import ValidationError
class AddUrlForm(forms.ModelForm):
class Meta:
model = forwards
# fields = '__all__'
exclude = ["user", "counterA", "counterB", "shortcodeurl", "uniqueid"]
def clean_shortcodeurl(self):
data = self.cleaned_data['shortcodeurl']
if "my_custom_example_url" not in data:
raise ValidationError("my_custom_example_url has to be in the provided data.")
return data

Trouble with Django ModelChoiceField

Hi bit of a beginner question about using django's modelchoicefield in a form I'm building.
I just need get django to display a drop down list of ingredients in a form. I've gotten to the point where the page renders but the form does not, I was getting errors before so I am kind of perplexed at the moment. I was hoping for some guidance.
Using python 2.7.6 and django 1.6.2. If I left anything out let me know.
Thanks!
Code is below:
views:
args = {}
#add csrf sercurity
args.update(csrf(request))
args['form'] = form
return render_to_response('newMeal.html', args)
form:
from django import forms
from models import meals, ingredients, recipe
class mealForm(forms.ModelForm):
breakfast = forms.ModelChoiceField(queryset=recipe.objects.all())
# Lunch = forms.ModelChoiceField(queryset=recipe.objects.all())
# Dinner = forms.ModelChoiceField(queryset=recipe.objects.all())
class Meta:
model = meals
fields = ('Breakfast','Lunch','Dinner','servingDate')
class recipeForm(forms.ModelForm):
class Meta:
model = recipe
fields = ('Name', 'Directions')
template:
{% extends "base.html" %}
{% block content %}
<p>New Meals go here!</p>
<form action="/meals/newmeal/" method="post">{% csrf_token %}
<table class="selection">
{{form.as_table}}
<tr><td colspan="2"><input type="submit" name="submit" value="Add Meal"></td></tr>
</table>
</form>
{% endblock %}
Model;
from django.db import models
import datetime
Create your models here.
class recipe(models.Model):
Name = models.CharField(max_length=200)
Directions = models.TextField()
pub_date = models.DateTimeField(auto_now_add = True)
def __unicode__(self):
return (self.id, self.Name)
class ingredients(models.Model):
Name = models.CharField(max_length=200)
Quantity = models.IntegerField(default=0)
Units = models.CharField(max_length=10)
Recipe = models.ForeignKey(recipe)
def __unicode__(self):
return self.Name
class meals(models.Model):
Breakfast = models.CharField(max_length=200)
Lunch = models.CharField(max_length=200)
Dinner = models.CharField(max_length=200)
servingDate = models.DateTimeField('date published')
did you import the mealForm:
some thing like :from app.forms import mealForm
form is a function. so try:
args['form'] = mealForm()
Note: don't use render_to_response. it is old use render instead(so don't even need csrf)::
from django.shortcuts import render
def...(request):
....
return render(request,'newMeal.html', {'form': mealForm()})

Categories