Django ChoiceField with custom forms - html

I am relatively new to Django and have been following up some tutorials on how to create registration forms with Django.
This is the html form code
<form action="{% url 'register' %}" method="post">
{% csrf_token %}
<div class="form-row">
<div class="col form-group">
<label>First name</label>
{{ form.first_name }}
</div> <!-- form-group end.// -->
<div class="col form-group">
<label>Last name</label>
{{ form.last_name }}
</div> <!-- form-group end.// -->
</div> <!-- form-row end.// -->
<div class="form-row">
<div class="col form-group">
<label>Email</label>
{{ form.email }}
</div> <!-- form-group end.// -->
<div class="form-group col-md-6">
<label>Directorate</label>
<select name="directorate" class="form-control" required>
<option value="" disabled selected>Select</option>
{% for i in form.directorate %}
<option value=""></option>
{% endfor %}
</select>
</div> <!-- form-group end.// -->
</div> <!-- form-row end.// -->
<div class="form-row">
<div class="form-group col-md-6">
<label>Create password</label>
{{ form.password }}
</div> <!-- form-group end.// -->
<div class="form-group col-md-6">
<label>Repeat password</label>
{{ form.confirm_password }}
</div> <!-- form-group end.// -->
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block"> Register </button>
</div> <!-- form-group// -->
</form>
models.py
class Account(AbstractBaseUser):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
username = models.CharField(max_length=50, unique=True)
email = models.EmailField(max_length=100, unique=True)
directorate = models.CharField(max_length=100)
# required
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now_add=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
is_superadmin = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'first_name', 'last_name']
objects = MyAccountManager()
views.py
from django.http import HttpResponse
from django.shortcuts import render
from .forms import RegistrationForm
from .models import Account
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
email = form.cleaned_data['email']
username = email.split('#')[0]
password = form.cleaned_data['password']
directorate = form.cleaned_data['directorate']
user = Account.objects.create_user(first_name=first_name, last_name=last_name, email=email, directorate=directorate, username=username, password=password)
user.save()
else:
form = RegistrationForm()
context = {
'form': form,
}
return render(request, 'accounts/register.html', context)
forms.py
from django import forms
from .models import Account
DIRECTORATE_CHOICES = [
("E", "Education"),
("H", "Health"),
("T", "Transport"),
]
class DirectorateChoices(forms.Form):
directorate = forms.ChoiceField(choices=DIRECTORATE_CHOICES,widget=forms.Select(attrs={
'class':'form-control'}), required=True)
class RegistrationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(attrs={
'placeholder': 'Enter your password',
}))
confirm_password = forms.CharField(widget=forms.PasswordInput(attrs={
'placeholder': 'Confirm your password',
}))
class Meta:
model = Account
fields = ['first_name', 'last_name', 'email', 'directorate', 'password']
def __init__(self, *args, **kwargs):
super(RegistrationForm, self).__init__(*args, **kwargs)
self.fields['first_name'].widget.attrs['placeholder'] = 'First name'
self.fields['last_name'].widget.attrs['placeholder'] = 'Last name'
self.fields['email'].widget.attrs['placeholder'] = 'Email address'
self.fields['directorate'].widget.attrs['placeholder'] = 'Select your directorate'
self.fields['password'].widget.attrs['placeholder'] = 'Enter password'
self.fields['confirm_password'].widget.attrs['placeholder'] = 'Confirm password'
for field in self.fields:
self.fields[field].widget.attrs['class'] = 'form-control'
I however want to introduce a ChoiceField on my registration form but from the reading and Youtube guide's I have followed, the field that is supposed to be loading the choices is not loading. This is my registration form

Related

Can't passe form's attrs in ModelForm to Template

I'm trying to set a ModelForm, but I don't get the attrs that I set in my Form in the Template.
Also, I want to get the date input in the format dd/mm/yyyy,
This is my model:
class Delivery(models.Model):
user = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name=_("delivery_user"))
full_name_reciever = models.CharField(_("Reciever Full Name"), max_length=50)
pickup_address = models.ForeignKey(Address, on_delete=models.CASCADE, related_name=_("pickup_address"))
destination_address = models.CharField(max_length=250)
destination_city = models.ForeignKey(City, on_delete=models.CASCADE, related_name=_("delivery_city"))
destination_post_code = models.CharField(max_length=20)
operation_date = models.DateField(
_("desired pickup date"), auto_now=False, auto_now_add=False, blank=False, null=False
)
boxes_number = models.PositiveIntegerField(_("Number of Boxes"), default=1)
boxes_wight = models.PositiveIntegerField(_("Boxes Wight"), default=1)
boxes_volume = models.PositiveIntegerField(_("Boxes Volume"), default=0)
document = models.FileField(
help_text=_("Delivery Documets"),
verbose_name=_("Delivery Certificates"),
upload_to="documents/deliveries_documents/",
)
invoice = models.BooleanField(_("check if you want an invoice"), default=False)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True, editable=False)
updated_at = models.DateTimeField(_("Updated at"), auto_now=True)
delivery_key = models.CharField(max_length=200)
billing_status = models.BooleanField(default=False)
delivery_status = models.BooleanField(default=False)
class Meta:
ordering = ("-created_at",)
verbose_name = _("Delivery")
verbose_name_plural = _("Deliveries")
def __str__(self):
return str(self.created_at)
The ModelForm:
class UserDeliveryForm(forms.ModelForm):
class Meta:
model = Delivery
fields = [
"full_name_reciever",
"pickup_address",
"destination_address",
"destination_city",
"destination_post_code",
"operation_date",
"boxes_number",
"boxes_wight",
"boxes_volume",
"document",
"invoice",
"delivery_key",
"billing_status",
"delivery_status",
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["full_name_reciever"].widget.attrs.update(
{"class": "form-control mb-2 delivery-form", "Placeholder": "full name reciever "}
)
self.fields["pickup_address"].widget.attrs.update(
{"class": "form-control mb-2 delivery-form", "Placeholder": "pickup address "}
)
self.fields["destination_address"].widget.attrs.update(
{"class": "form-control mb-2 delivery-form", "Placeholder": "destination address"}
)
self.fields["destination_city"].widget.attrs.update(
{"class": "form-control mb-2 delivery-form", "Placeholder": "destination city"}
)
self.fields["destination_post_code"].widget.attrs.update(
{"class": "form-control mb-2 delivery-form", "Placeholder": "Post Code"}
)
self.fields["operation_date"].widget.attrs.update(
{"class": "form-control mb-2 delivery-form", "Placeholder": "operation date"}
)
self.fields["boxes_number"].widget.attrs.update(
{"class": "form-control mb-2 delivery-form", "Placeholder": "boxes number"}
)
self.fields["boxes_wight"].widget.attrs.update(
{"class": "form-control mb-2 delivery-form", "Placeholder": "boxes wight"}
)
self.fields["boxes_volume"].widget.attrs.update(
{"class": "form-control mb-2 delivery-form", "Placeholder": "boxes volume"}
)
self.fields["document"].widget.attrs.update(
{"multiple": True, "class": "form-control mb-2 delivery-form", "Placeholder": "document"}
)
self.fields["invoice"].widget.attrs.update(
{"class": "form-control mb-2 delivery-form", "Placeholder": "invoice"}
)
self.fields["delivery_key"].widget.attrs.update(
{"class": "form-control mb-2 delivery-form", "Placeholder": "delivery key"}
)
self.fields["billing_status"].widget.attrs.update(
{"class": "form-control mb-2 delivery-form", "Placeholder": "billing status"}
)
self.fields["delivery_status"].widget.attrs.update(
{"class": "form-control mb-2 delivery-form", "Placeholder": "delivery status"}
)
And my view:
class DeliveryCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
model = Delivery
fields = [
"full_name_reciever",
"pickup_address",
"destination_address",
"destination_city",
"destination_post_code",
"operation_date",
"boxes_number",
"boxes_wight",
"boxes_volume",
"document",
"invoice",
"delivery_key",
"billing_status",
"delivery_status",
]
template_name = "deliveries/customer/edit_deliveries.html"
success_url = reverse_lazy("account:dashboard")
def test_func(self):
return self.request.user.is_customer and self.request.user.is_active
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
files = request.FILES.getlist("decument")
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form):
form.instance.user_id = self.request.user.id
return super().form_valid(form)
I want to get a date picket in my Template using the date format dd/mm/yyyy, but when I specify the input type manually to "date" in the template I get format mm/dd/yyyy with a date picker.
This is the Template I use:
{% extends "../../account/sub_base.html" %}
{% load l10n %}
{% block title %}Edit Delivery{% endblock %}
{% block sub_content %}
<div class=" col-lg-10 mx-auto">
<h1 class="h3">Create/Edit Delivery</h1>
<div>Add a new <b>Delivery</b> </div>
<hr />
<form name="delivery_form" class="delivery-form" method="post" enctype="multipart/form-data">
{% if form.errors %}
{{form.errors}}
<div class="alert alert-primary" role="alert">
Error: Please try again!
</div>
{% endif %}
{% csrf_token %}
<div class="form-group">
<label class="small fw-bold">{{ form.full_name_reciever.label}}</label>
{{ form.full_name_reciever }}
</div>
<div class="form-group">
<label class="small fw-bold">{{ form.pickup_address.label}}</label>
{{form.pickup_address }}
</div>
<div class="form-group">
<label class="small fw-bold">{{ form.destination_address.label}}</label>
{{ form.destination_address }}</div>
<div class="form-group">
<label class="small fw-bold">{{ form.destination_city.label}}</label>
{{ form.destination_city }}</div>
<div>
<label class="small fw-bold">{{ form.destination_post_code.label}}</label>
{{ form.destination_post_code }}
</div>
{% localize on %}
<div class="form-group">
<label class="small fw-bold">{{ form.operation_date.label}}</label>
{{ form.operation_date }}
</div>
{% endlocalize %}
<div>
<label class="small fw-bold">{{ form.boxes_number.label}}</label>
{{ form.boxes_number }}
</div>
<div>
<label class="small fw-bold">{{ form.boxes_wight.label}}</label>
{{ form.boxes_wight }}
</div>
<div>
<label class="small fw-bold">{{ form.boxes_volume.label}}</label>
{{ form.boxes_volume }}
</div>
<div>
<label class="small fw-bold">{{ form.document.label}}</label>
<input type="file" multiple value={{ form.document }}>
</div>
<div class="form-group form-check">
<label class="small fw-bold">{{ form.invoice.label}}</label>
{{ form.invoice }}
</div>
<div>
<label class="small fw-bold">{{ form.delivery_key.label}}</label>
{{ form.delivery_key }}
</div>
<div class="form-group form-check">
<label class="small fw-bold">{{ form.delivery_status.label}}</label>
<input type="checkbox" class="form-check-input" value={{ form.delivery_status }} </div>
<button class="btn btn-primary btn-block py-2 mb-4 mt-4 fw-bold w-100" type="button" value="Submit"
onclick="submitForm()">
Add Delivery
</button>
</form>
</div>
<script>
function submitForm() {
var form = document.getElementsByName('delivery_form')[0];
form.submit(); // Submit the form
form.reset(); // Reset all form data
return false; // Prevent page refresh
}
</script>
{% endblock %}
Also even though I set the form to accept multiple file upload, I need to manually set that in my template. also the css class='form-control' that don't work from widgets setting in the form.
you can use flowing code in ModelForm class :
operation_date = forms.DateField(widget=forms.DateInput(
attrs={"type": 'date', 'required': False, 'value': datetime.datetime.today().strftime('%Y-%d-%m')}), label=_("Date"))
I Fixed the probleme, I figured out that I didn't assigned the Mofelform to the context data of the Modelview.
This is the ModelView:
class DeliveryCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
model = Delivery
form_class = UserDeliveryForm
template_name = "deliveries/customer/edit_deliveries.html"
success_url = reverse_lazy("account:dashboard")
def test_func(self):
return self.request.user.is_customer and self.request.user.is_active
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
files = request.FILES.getlist("decument")
if form.is_valid():
for f in files:
f.save()
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form):
form.instance.user_id = self.request.user.id
return super().form_valid(form)
This is the result I get:

Modifying a dropdown menu option in a form Django

I have a dropdown menu that i'm using to fill a field on a form, but, as i'm just starting with django and html, i'm using another form to edit and update the data of the previous form. But i cant make the dropdown menu to work on that second form.
The model:
class Orden(models.Model):
STATUS = (
('En espera', 'En espera'),
('En proceso', 'En proceso'),
('Terminado', 'Terminado'),
('Entregado', 'Entregado'),
)
num_orden = models.CharField(max_length=20, default='')
fechain = models.CharField(max_length=30, default='')
fechaout = models.CharField(max_length=30, default='')
instrumento = models.CharField(max_length=30, default='')
marca = models.CharField(max_length=20)
referencia = models.CharField(max_length=30, default='')
serial = models.CharField(max_length=15, default='')
encargado = models.CharField(max_length=50, default='')
abono = models.CharField(max_length=15, default='')
procesos = models.TextField(default='')
estado = models.CharField(max_length=50, null=True, choices=STATUS) # <--- This one
client = models.ForeignKey(Cliente, on_delete=models.CASCADE, default='', related_name="client")
The view related to the first form:
def ordenfill(request, client_id):
if request.method == 'POST':
orden = ordenForm(request.POST)
if orden.is_valid():
orden.instance.client_id = client_id
init = orden.save()
return redirect('ordenview', id=init.id)
else:
orden = ordenForm()
client = Cliente.objects.get(id=client_id)
context = {
'orden': orden,
'client': client,
}
return render(request, 'ordenfill.html', context)
The template part asociated to that dropdown menu:
<form method="POST" class="post-form" action="{% url 'ordenfill' client.id %}">
{% csrf_token %}
<div class="container">
<br>
.
.
.
<div class="form-group row">
<label class="col-sm-2 col-form-label">Estado</label>
<div class="col-sm-4">
{{orden.estado}}
</div>
</div>
</div>
</form>
Image of the First Form
Dropdown menu on the first form
The view related to the second form:
def ordenupd(request, id):
orden = Orden.objects.get(id=id)
status = Orden.STATUS
context = {
'orden': orden,
'status': status,
}
return render(request, "ordenupd.html", context)
Edit: the view that saves the changes in the second form
def ordenmod(request, id):
orden = get_object_or_404(Orden, id=id)
if request.method == 'GET':
orden = ordenForm(instance=orden)
return redirect("ordenview", id=id)
else:
orden = ordenForm(request.POST, instance=orden)
print(orden.errors)
if orden.is_valid():
orden.save()
return redirect("ordenview", id=id)
else:
orden = clienteForm()
return redirect("ordenview", id=id)
The template part asociated to the dropdown menu of that view:
<form method="POST" class="post-form" action="/ordenmod/{{orden.id}}">
<input type="hidden" name="id" id="id" required maxlength="20" value="{{orden.id}}"/>
{% csrf_token %}
<div class="container">
<br>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Estado</label>
<div class="col-sm-4">
<select name="select_path" id="select_path">
<option value="{{orden.estado}}">{{orden.estado}}</option>
{% for items in status %}
<option value ="{{orden.estado}}">{{orden.estado}}</option>
{% endfor %}
</select>
</div>
</div>
</div>
</form>
And the webpage of that view:
Dropdown menu on the second form
How can i make that dropdown menu on the second form to work like the one on the first form?
#chnage your view as below
from .models import STATUS
def ordenupd(request, id):
status = STATUS
context = {
'status': status,
}
return render(request, "ordenupd.html", context)
#change your HTML form template as below
<form method="POST" class="post-form" action="/ordenmod/{{orden.id}}">
<input type="hidden" name="id" id="id" required maxlength="20" value="{{orden.id}}"/>
{% csrf_token %}
<div class="container">
<br>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Estado</label>
<div class="col-sm-4">
<select name="select_path" id="select_path">
{% for items in status %}
<option value ="{{item.1}}">{{item.1}}</option>
{% endfor %}
</select>
</div>
</div>
</div>
</form>

how to show data through input tag

I am working on a Django project .In front-end I want to add user data through input tags but I do not know how to save data through input tags
My models.py file is::
class User(AbstractBaseUser):
full_name = models.CharField(max_length=255, blank=True, null=True)
sur_name = models.CharField(max_length=255, blank=True, null=True)
email = models.EmailField(max_length=255 ,unique=True)
choose_subject = models.CharField(choices=SUBJECT_CHOICES , max_length=100)
staff = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
time_stamp = models.DateTimeField(auto_now_add=True)
father_name = models.CharField(max_length=255)
father_sur_name = models.CharField(max_length=255)
mobile_phone_number = models.IntegerField(blank=True,null=True)
father_email = models.EmailField(max_length=255, unique=True)
fiscal_code = models.CharField(max_length=20)
address = models.CharField(max_length=200 )
A part of my register.html file is:
<div class="card-body">
<h2 class="title">Registration Form</h2>
<form method="POST">{% csrf_token %}
<div class="row row-space">
<div class="col-2">
<div class="input-group">
<label class="label">Full name</label>
<input class="input--style-4" type="text" name="first_name"{{form.full_name}}>
</div>
</div>
<div class="col-2">
<div class="input-group">
<label class="label">Sur name</label>
<input class="input--style-4" type="text" name="last_name"{{form.sur_name}}>
</div>
</div>
</div>
I just want the Django model field to be working in input tags
You must create in the views.py file a method in which the templates and the logic of it, an example can be the following
views.py
#csrf_exempt
def register(request):
if request.method == 'POST':
var1 = request.POST.get('var1')
var2 = request.POST.get('var2')
var3 = request.POST.get('var3')
#Save to the database here
return render_to_response(
'home.html',
{'message': 'Update Success', }
)
else:
#elif request.method == "GET":
obj = table.objects.all()
if obj:
ctx['data'] = obj
return render(request, template_name, ctx)
and in your template add a form tag
<form method="POST">
{ % csrf_token % }
<div class="row row-space">
<div class="col-2">
<div class="input-group">
<label class="label">Full name</label>
<input class="input--style-4" type="text" value={{data.full_name}}>
</div>
</div>
<div class="col-2">
<div class="input-group">
<label class="label">Sur name</label>
<input class="input--style-4" type="text" value={{data.sur_name}}>
</div>
</div>
</div>
<input type="submit" value="OK">
</form>
refer this tutorial

Why doesn't the Django formset appear?

I have one form and one formset on the same page. Prior to my deletion of information from django admin, I could see both the form and the formset. After I deleted some 'patient' information and updated my css file, the formset stopped showing.
views.py
def patient_new(request):
patientForm = PatientForm()
formset = LocationFormSet()
if request.method == "POST":
patientForm = PatientForm(request.POST)
formset = LocationFormSet(request.POST)
if patientForm.is_valid() and formset.is_valid():
patient = patientForm.save(commit=True)
for form in formset:
location = form.save(commit=False)
location.patient = patient
location.save()
return index(request)
else:
print('ERROR FORM INVALID')
return render(request, 'covidapp/patient_new.html',{'patientForm':patientForm, 'formset':formset})
html file
<form class="form-horizontal" method="POST">
{% csrf_token %}
<div class="jumbotron">
<div class="row spacer">
<div class="col-2">
<div class="input-group">
{{ patientForm.as_p }}
</div>
</div>
</div>
{{ formset.management_form }}
{% for form in formset %}
<div class="row form-row spacer">
<div class="col-6">
<div class="input-group">
{{ form.as_p }}
<div class="input-group-append">
<button type="button" class="btn btn-success add-form-row">+</button>
</div>
</div>
</div>
</div>
{% endfor %}
<div class="row spacer">
<div class="col-4 offset-2"></div>
<button type="submit" class="btn btn-block btn-primary">Create</button>
</div>
</div>
</form>
html output
I am not sure whether the hidden input is supposed to be my formset and why it is hidden.
model.py
class Patient(models.Model):
name = models.CharField(max_length=200)
idn = models.IntegerField(unique=True)
date_of_birth = models.DateField()
date_of_confirm = models.DateField()
case_number = models.IntegerField()
def get_absolute_url(self):
return reverse("patient_detail", kwargs={'pk':self.pk})
def __str__(self):
return self.name
class Location(models.Model):
patient = models.ForeignKey(Patient, related_name='locations', on_delete=models.CASCADE)
location_name = models.CharField(max_length=50, null=True)
address = models.CharField(max_length=300, null=True)
grid_x = models.IntegerField(null=True)
grid_y = models.IntegerField(null=True)
date_from = models.DateField(null=True)
date_to = models.DateField(null=True)
details = models.CharField(max_length=300, null=True)
category = models.CharField(max_length=300, null=True)
def __str__(self):
return self.location_name
form.py
class PatientForm(forms.ModelForm):
class Meta:
model = Patient
fields = '__all__'
LocationFormSet = modelformset_factory(
Location,
extra=0,
exclude = ('patient',)
)

Appear data in URL form bu using Django

I want to create a record and want to appear data in the form fields. How can I do that ? Do I need to write javascript for it. If you help me, really apprepriate it. Thanks for now.
Here is models.py;
class hesaplarim(models.Model):
hesap_id = models.AutoField(primary_key=True)
tc_no = models.IntegerField(unique=True)
name = models.CharField(max_length=55)
surname = models.CharField(max_length=55)
phone_number = models.IntegerField()
gender = models.CharField(max_length=5)
Here is views.py;
def home(request):
form = HesapForm(request.POST or None)
if form.is_valid():
form.save()
return HttpResponseRedirect('/')
else:
form = HesapForm()
return render(request, 'home.html', {'form': form})
Here is forms.py;
class HesapForm(forms.ModelForm):
ERKEK = 'ERKEK'
KADIN = 'KADIN'
gender_choices = (
(ERKEK, 'ERKEK'),
(KADIN, 'KADIN')
)
tc_no = forms.IntegerField(widget=forms.NumberInput)
name = forms.CharField(widget=forms.TextInput)
surname = forms.CharField(widget=forms.TextInput)
phone_number = forms.IntegerField(widget=forms.NumberInput)
gender = forms.ChoiceField(choices=gender_choices)
class Meta:
model = hesaplarim
fields = ('tc_no', 'name', 'surname', 'phone_number',
'gender')
Here is html file;
<form method="post" class="form-horizontal" novalidate>
{% csrf_token %}
<div class="form-group">
<label for="id_tc_no">TC No:</label>
{{ form.tc_no }}
</div>
<div class="form-group">
<label for="id_name">Ad:</label>
{{ form.name }}
</div>
<div class="form-group">
<label for="id_surname">Soyad:</label>
{{ form.surname }}
</div>
<div class="form-group">
<label for="id_phone">Cep Telefonu:</label>
{{ form.phone_number }}
</div>
<div class="form-group">
<label for="id_gender">Cinsiyet:</label>
{{ form.gender }}
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Kaydet">
</div>
</form>
You need to initialize the form:
def home(request):
form = HesapForm(request.POST or None)
if form.is_valid():
form.save()
return HttpResponseRedirect('/')
else:
form = HesapForm(initial={'your_field': 'your_value'})
return render(request, 'home.html', {'form': form})
Dynamic initial values you can refer about the same here.
You can also initialize it with object as well.