I have created a form and a view in Django and I'm trying to display it in the HTML but it isn't loading anything and I don't know why.
alumno2.html
{% block header %}
<header class="masthead bg-white text-dark text-uppercase">
<div class="container">
<h3 class="text-center">Añadir alumno</h3>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-secondary" type="submit">Guardar</button>
</form>
</div>
</header>
{% endblock %}
form.py
class AlumnoForm2(forms.ModelForm):
class Meta:
model = Alumno
#fields = ['dni', 'nombre', 'apellido1', 'apellido2','email','repetidor']
fields = ['dni', 'nombre', 'apellido1', 'apellido2','email','repetidor','curs']
labels = {
'dni': 'dni',
'nombre': 'nombre',
'apellido1': 'Primer Apellido',
'apellido2': 'Segundo Apellido',
'email': 'Email',
'repetidor': 'repetidor',
'curs': 'curs'
}
widgets = {
'dni': forms.TextInput(attrs={'class': 'form-control'}),
'nombre': forms.TextInput(attrs={'class': 'form-control'}),
'apellido1': forms.TextInput(attrs={'class': 'form-control'}),
'apellido2': forms.TextInput(attrs={'class': 'form-control'}),
'email': forms.TextInput(attrs={'class': 'form-control'}),
'repetidor': forms.CheckboxInput(attrs={'class':'form-control-checkbox','id': 'repetidor'}),
'curs':forms.Select(attrs={'class': 'form-control'}),
}
view.py
class crea_alumno(CreateView):
model = Alumno
form_class = AlumnoForm2
template_name = '/alumno2.html'
success_url = reverse_lazy('mostrar_alumnos')
url.py
url(r'^alumno2/$', crea_alumno.as_view(),name='alumno2'),
models.py
class Alumno(models.Model):
dni = models.CharField(max_length=9,primary_key=True)
nombre = models.CharField(max_length=100)
apellido1 = models.CharField('Primer apellido',max_length=50)
apellido2 = models.CharField('Segundo apellido',max_length=50)
email = models.EmailField("Correo electronico",null=True)
repetidor = models.BooleanField()
curs = models.ManyToManyField(Curso, blank=True, related_name="Historico_de_cursos")
Nivel = models.ManyToManyField('Nivel', through = 'Completado',through_fields=('Alumno','Nivel'))
Practica = models.ManyToManyField('Practica', through = 'Nota',through_fields=('Alumno','Practica'))
Curso = models.ManyToManyField('Curso',through = 'Curso_alumno',through_fields=('Alumno','Curso'))
def __str__(self):
return self.dni
the html only display the save button, is not loading the create form. The html is inside the template folders thats why I have this urls.
EDIT:
I have removed the template I had also
url(r'^alumno2/$', TemplateView.as_view(template_name='alumno2.html'),name='alumno2'),
and I'm not sure if i need to put this in the url.py so now I only have the view and is unable to find my template withouth that
Remove the line
url(r'^alumno2/$', TemplateView.as_view(template_name='alumno2.html'),name='alumno2'),
from your urls.py and only keep this one:
url(r'^alumno2/$', crea_alumno.as_view(),name='alumno2'),
And inside your view, remove the / in the template name: instead of
template_name = '/alumno2.html'
Use
template_name = 'alumno2.html'
And replace CreateView with FormView as per the documentation
Related
I am using Crispy Forms with Bootstrap4. Currently, all the input fields are rendered with form-control class. I want to add form-control-lg to the input fields.
I have tried the following but it is not working
forms.py
class UserRegisterForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2', 'first_name', 'last_name']
help_texts = {
'username': None,
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['password1'].help_text = None
self.fields['password2'].help_text = None
self.fields['password2'].label = "Confirm Password"
self.helper = FormHelper()
self.helper.layout = Layout(
Field(
'username', css_class="form-control form-control-lg my-custom-class"
)
)
Template
<div class="content-section">
<form method="POST" action="">
<h3>Sign Up</h3>
<hr>
{% csrf_token %}
{{ form | crispy }}
</br>
<button type="submit" class="btn btn-primary">Sign Up</button>
</form>
</div>
Also, can I modify the class globally for all input fields?
Following the pattern you already have. Let's start with this method:
1.
class UserRegisterForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2', 'first_name', 'last_name']
help_texts = {
'username': None,
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['password1'].help_text = None
self.fields['password2'].help_text = None
self.fields['password2'].label = "Confirm Password"
self.helper = FormHelper()
# Attach to helper
self.helper.form_class = 'form-control-lg'
FormHelper has a list of attributes that can be set, that affect mainly form attributes.
Let’s see how to render the form in a template. Supposing we have the form in the template context as example_form, we would render it doing:
{% load crispy_forms_tags %}
{% crispy example_form example_form.helper %}
Notice that the {% crispy %} tags expects two parameters: first the form variable and then the helper. In this case we use the FormHelper attached to the form, but you could also create a FormHelper instance and pass it as a context variable. Most of the time, you will want to use the helper attached. Note that if you name your FormHelper attribute helper you will only need to do:
{% crispy form %}
Inside project settings.py add this line
CRISPY_CLASS_CONVERTERS = {'textinput': "textinput inputtext"}
For example this setting would generate <input class"textinput inputtext" .... The key of the dictionary textinput is the Django’s default class, the value is what you want it to be substituted with, in this case we are keeping textinput.
So from above you could substitute this way:
CRISPY_CLASS_CONVERTERS = {'input-control': "input-control-lg inputtext"}
References and quotes from Django Crispy Form Doc
Edit
Check this answer
\\models.py
class BasicSettings(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
default=None,
null=True,
on_delete=models.CASCADE,
)
settings_description = models.BooleanField(default=False)
settings_photo = models.BooleanField(default=False)
settings_username = models.BooleanField(default=False)
settings_background = models.BooleanField(default=False)
\\views.py
try:
basic_settings = request.user.basicsettings
except BasicSettings.DoesNotExist:
basic_settings = BasicSettings(user=request.user)
if request.method == 'POST':
basicsettings_form = BasicSettingsForm(
request.POST, instance=basic_settings)
else:
basicsettings_form = BasicSettingsForm(instance=basic_settings)
return render(request, 'dashboard.html', {'basicsettings_form': basicsettings_form})
\\forms.py
class BasicSettingsForm(forms.ModelForm):
class Meta:
model = BasicSettings
fields = (
'settings_description',
'settings_photo',
'settings_username',
'settings_background',
)
widgets = {
'settings_description': forms.TextInput(attrs={'type': 'checkbox', 'class': 'checkbox', 'id': 'test1'}),
'settings_photo': forms.TextInput(attrs={'type': 'checkbox', 'class': 'checkbox', 'id': 'test2'}),
'settings_username': forms.TextInput(attrs={'type': 'checkbox', 'class': 'checkbox', 'id': 'test3'}),
'settings_background': forms.TextInput(attrs={'type': 'checkbox', 'class': 'checkbox', 'id': 'test4'}),
}
\.html
<form method="POST">
{% csrf_token %}
{{ basicsettings_form }}
<button type="submit">Dad9adbaiduaadtest</button>
When I click on the submit button, the page just refreshes but nothing happens. What might be the reason for this?
The code above is just a snippet. Maybe nothing happens because I have multiple forms in one view? The whole view looks like this https://pastebin.com/Bu5NLTX1 but I just wanted to give you the relevant part
This might be the problem..
From Creating forms from models:
Every ModelForm also has a save() method. This method creates and saves a database object from the data bound to the form. A subclass of ModelForm can accept an existing model instance as the keyword argument instance; if this is supplied, save() will update that instance. If it’s not supplied, save() will create a new instance of the specified model:
So maybe try:
basicsettings_form = BasicSettingsForm(
request.POST, instance=basic_settings)
if basicsettings_form.is_valid():
basicsettings_form.save()
Have you added action in your form action=your_action_url
<form action ="{% url 'your_url_name' %}" method="POST">
{% csrf_token %}
{{ basicsettings_form }}
<button type="submit">Dad9adbaiduaadtest</button>
I am using class Based view for update my Blog post but validation error message not showing in my Django template html. Here is my code:
froms.py
from .models import *
from django import forms
from django.core.exceptions import ValidationError
class BlogPost(forms.ModelForm):
class Meta:
model = Post
fields = ['title','author','body']
widgets = {
'title': forms.TextInput(attrs={'class':'form-control'}),
'author': forms.Select(attrs={'class':'form-control'}),
'body': RichTextField(),
}
def clean(self):
cleaned_data = super(BlogPost,self).clean()
title = cleaned_data.get('title')
if title:
if title(name)<30:
count_text = len(title)
raise ValidationError("Title is too short")
views.py
class blog_update_view(UpdateView):
model = Post
template_name = "blog_update_post.html"
form_class = BlogPost
html
{% form.non_field_errors %}
<form method="POST">
{% csrf_token %}
{{form.media}}
{{form.as_p}}
<button class="btn btn-info">Publish</button>
</form>
</div>
I also want to know how to handle others error in django-form such as integrityerror in class based view.
Your function is not properly indented, you should place this in the scope of the .clean(…) method:
class BlogPost(forms.ModelForm):
class Meta:
model = Post
fields = ['title','author','body']
widgets = {
'title': forms.TextInput(attrs={'class':'form-control'}),
'author': forms.Select(attrs={'class':'form-control'}),
'body': RichTextField(),
}
def clean(self):
cleaned_data = super().clean()
title = cleaned_data.get('title')
if title:
if len(title) < 30:
count_text = len(title)
raise ValidationError("Title is too short")
return cleaned_data
But it makes more sense here to put in in the clean_title method, since then it is attached to the title field:
class BlogPost(forms.ModelForm):
class Meta:
model = Post
fields = ['title','author','body']
widgets = {
'title': forms.TextInput(attrs={'class':'form-control'}),
'author': forms.Select(attrs={'class':'form-control'}),
'body': RichTextField(),
}
def clean_title(self):
title = self.cleaned_data['title']
if title and len(title) < 30:
raise ValidationError("Title is too short")
return title
A CharField [Django-doc] has a min_length=… [Django-doc] that can be used:
class BlogPost(forms.ModelForm):
title = forms.CharField(
min_length=30,
widget=forms.TextInput(attrs={'class':'form-control'})
)
class Meta:
model = Post
fields = ['title','author','body']
widgets = {
'author': forms.Select(attrs={'class':'form-control'}),
'body': RichTextField(),
}
I want to when i click on the user discharge button it will go to the page and the all user information take automatically. But i cannot get this value. Here is the image in the discharge button i click but its shows like this.
Here is my code : views.py
def discharge_view(request, pk):
form = DischargForm()
if request.method == 'POST':
form = DischargForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Successfull')
return redirect('discharge-patient')
context = {
'form': form,
}
return render(request, 'hospital/discharge.html', context)
forms.py :
class DischargForm(forms.ModelForm):
class Meta:
model = PatientDischarge
fields = ('assign_doctor', 'admitted', 'release_date', 'medicine_cost', 'other_charge')
widgets = {
'assign_doctor': forms.Select(attrs={'class': 'form-control'}),
'admitted': forms.Select(attrs={'class': 'form-control'}),
'release_date': forms.TextInput(attrs={'class': 'form-control'}),
'medicine_cost': forms.TextInput(attrs={'class': 'form-control'}),
'other_charge': forms.TextInput(attrs={'class': 'form-control'}),
}
models.py
class PatientDischarge(models.Model):
assign_doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
admitted = models.ForeignKey(Admitted, on_delete=models.CASCADE)
release_date = models.DateField(auto_now_add=False)
medicine_cost = models.IntegerField(null=True)
other_charge = models.IntegerField()
def __str__(self):
return self.admitted.patient_name if all([self.admitted, self.admitted.patient_name]) else 0
def days_count(self):
return self.release_date - self.admitted.admited_date if all([self.admitted, self.admitted.admited_date]) else 0
def room_bill(self):
return self.days_count() * self.admitted.room_service if all([self.admitted, self.admitted.room_service]) else 0
def total_bill(self):
return self.room_bill().days + self.medicine_cost + self.other_charge
discharge.html
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% for fields in form %}
<div class="form-group"></div>
{{ fields.label_tag }}
{{ fields }}
{% endfor %}
<br>
<input type="submit" value="Submit">
To pass an instance to the form you can do this form = DischargForm(instance=<DischargeInstance>) and the template will have pre-filled values in the form as per the instance.
Can you provide your models.py.
I have formset and form in one page, both are saved at the same time. But new records for event time are not saved, only old records are updated. Where is the problem?
formset:
class EventTimeForm(forms.ModelForm):
class Meta:
model = EventTime
fields = ['start_time']
widgets = {
'start_time': DateTimeWidget(usel10n=True, bootstrap_version=3)
}
EventTimeFormSet = modelformset_factory(EventTime, form=EventTimeForm, max_num=3, extra=3)
form:
class CreateEventForm(forms.ModelForm):
class Meta:
model = Event
fields = ['title', 'description', 'location', 'duaration', 'private']
view:
def create_event(request):
event_form = CreateEventForm(request.POST or None, prefix='event')
event_time_form = EventTimeFormSet(request.POST or None, prefix='eventtime')
context = {
'event_form': event_form,
'event_time_form': event_time_form,
}
if event_form.is_valid() and event_time_form.is_valid():
event = event_form.save()
event_time = event_time_form.save()
for obj in event_time:
obj.event.add(event)
return HttpResponseRedirect('/event-%s' %event.id)
return render(request, 'create_event.html', context)
template:
<form method='POST' action=''>{%csrf_token%}
{{ event_time_form|crispy }}
{{ event_form|crispy}}
<input class="btn btn-primary" type="submit" value="Create" />
</form>