Build fast, responsive sites with Bootstrap
Quickly design and customize responsive mobile-first sites with Bootstrap, the world’s most popular front-end open source toolkit, featuring Sass variables and mixins, responsive grid system, extensive prebuilt components, and powerful JavaScript plugins.
Currently v5.1.3 · v4.6.x docs · All releases
Installation
Install Bootstrap’s source Sass and JavaScript files via npm, Composer, or Meteor.
Package managed installs don’t include documentation or our full build scripts. You can also use our npm template repo
Read installation docs$ npm install bootstrap
$ gem install bootstrap -v 5.1.3
jsDelivr
When you only need to include Bootstrap’s compiled CSS or JS, you can use jsDelivr.
See it in action with our simple starter template , or browse the examples to jumpstart your next project. You can also choose to include Popper and our JS separately .
Explore the docs
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqy" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous">
$ django-admin startproject "nombreDelProyecto"
$ cd nombreDelProyecto
$ python manage.py runserver
$ python manage.py startapp "nombreApp"
INSTALLED_APPS = [
...,
'nombreApp',
]
from django.http import HttpResponse
def index(request):
return HttpResponse("Hola mundo")
from django.urls import path
from nombreApp.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path('', index, name='index'),
]
One Page con JavaScript
Carga contenido dinámico cuando el usuario llega al final de la página.
Ver documentación
// Detectar scroll hasta el final
window.addEventListener('scroll', () => {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
loadCards();
}
});
function loadCards(title, text) {
var card = document.createElement('div');
card.setAttribute('class', 'card col-4');
var body = document.createElement('div');
body.setAttribute('class', 'card-body');
var h5 = document.createElement('h5');
h5.setAttribute('class', 'card-title');
h5.innerHTML = title;
var p = document.createElement('p');
p.setAttribute('class', 'card-text');
p.innerHTML = text;
body.appendChild(h5);
body.appendChild(p);
card.appendChild(body);
document.getElementById('tarjetas').appendChild(card);
}
var i = 1;
window.addEventListener('scroll', () => {
if ((window.scrollY + window.innerHeight) >= document.body.offsetHeight) {
for (let index = 0; index < 5; index++) {
if (i > 100) { break; }
var object = {
title: 'Título dinámico de la Card: ' + i,
text: 'Texto dinámico de la Card: ' + i
}
loadCards(object.title, object.text);
i++;
}
}
});
DataTables
Configuración de base de datos y modelo en Django para integrar DataTables.
Ver documentaciónCREATE DATABASE mi_base_de_datos;
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mi_base_de_datos',
'USER': 'root',
'PASSWORD': 'root',
'HOST': 'localhost',
'PORT': '3306',
}
}
$ pip install pymysql
import pymysql
pymysql.install_as_MySQLdb()
from django.db import models
class Cancion(models.Model):
titulo = models.CharField(max_length=200)
autor = models.CharField(max_length=100)
duracion = models.FloatField()
def __str__(self):
return self.titulo
from django.shortcuts import render
from .models import Cancion
def lista_canciones(request):
canciones = Cancion.objects.all() # Obtener todas las canciones
return render(request, 'tabla.html', {'canciones': canciones})
<!-- HTML para mostrar las canciones con DataTables -->
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lista de Canciones</title>
<!-- Estilos y Scripts de DataTables -->
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
</head>
<body>
<h2>Lista de Canciones</h2>
<table id="tabla-canciones" class="display">
<thead>
<tr>
<th>Título</th>
<th>Autor</th>
<th>Duración</th>
</tr>
</thead>
<tbody>
{% for cancion in canciones %}
<tr>
<td>{{ cancion.titulo }}</td>
<td>{{ cancion.autor }}</td>
<td>{{ cancion.duracion }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<script>
$(document).ready( function () {
$('#tabla-canciones').DataTable();
});
</script>
</body>
</html>
from django.urls import path
from .views import lista_canciones
urlpatterns = [
path('canciones/', lista_canciones, name='lista_canciones'),
]
$ python manage.py makemigrations
$ python manage.py migrate
🔹 Paso 1: Crear una nueva aplicación
$ python manage.py startapp app2
🔹 Paso 2: Registrar la aplicación en INSTALLED_APPS
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app',
'app2',
]
🔹 Paso 3: Configurar AUTH_USER_MODEL
AUTH_USER_MODEL = 'users.CustomUser'
🔹 Paso 4: Crear un modelo personalizado en models.py
Define un modelo de usuario personalizado en la aplicación `app2`.
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.db import models
from django.utils.timezone import now
class CustomUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError('El correo electrónico es obligatorio')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
return self.create_user(email, password, **extra_fields)
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
name = models.CharField(max_length=100)
surname = models.CharField(max_length=100)
control_number = models.CharField(max_length=20, unique=True)
age = models.PositiveIntegerField()
tel = models.CharField(max_length=15)
join_date = models.DateTimeField(default=now)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = CustomUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name', 'surname', 'control_number', 'age', 'tel']
def __str__(self):
return self.email
🔹 Paso 5: Crear un archivo forms.py
Define el formulario de registro y autenticación.
from django import forms
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ['email', 'name', 'surname', 'control_number', 'age', 'tel', 'password1', 'password2']
class CustomUserLoginForm(AuthenticationForm):
pass
🔹 Paso 6: Migrar la base de datos
Ejecuta los siguientes comandos para aplicar los cambios en la base de datos.
$ python manage.py makemigrations
$ python manage.py migrate
Validaciones
Validaciones en Django tanto desde el backend como desde el frontend.
Ver documentación🔹 Validación desde Back
from django import forms
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ['email', 'name', 'surname', 'control_number', 'age', 'tel', 'password1', 'password2']
widgets = {
'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Correo electrónico', 'required': True}),
'password1': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Contraseña', 'required': True}),
}
import re
from django.contrib.auth import authenticate
class CustomUserLoginForm(AuthenticationForm):
username = forms.CharField(label="Correo electrónico", max_length=150)
password = forms.CharField(label="Contraseña", widget=forms.PasswordInput)
def clean(self):
cleaned_data = super().clean()
email = cleaned_data.get("username")
password = cleaned_data.get("password")
if email and not re.match(r"^[a-zA-Z0-9._%+-]+@utez\.edu\.mx$", email):
raise forms.ValidationError("El correo debe pertenecer a @utez.edu.mx.")
if password and not re.match(r"^(?=.*[0-9])(?=.*[!#$%&?]).{8,}$", password):
raise forms.ValidationError("La contraseña debe tener al menos 8 caracteres, incluir un número y un símbolo.")
user = authenticate(username=email, password=password)
if not user:
raise forms.ValidationError("Usuario o contraseña incorrectos.")
return cleaned_data
🔹 Validación desde Front
<div class="form-container">
<h2 class="mb-4">Registro</h2>
<form method="post" onsubmit="return validateForm()">
{% csrf_token %}
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Correo electrónico</label>
<input type="email" name="email" class="form-control" required
pattern="^[a-zA-Z0-9]+@utez\.edu\.mx$"
title="El correo debe ser institucional @utez.edu.mx">
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Contraseña</label>
<input type="password" id="password1" name="password1" class="form-control" required minlength="8">
</div>
</div>
<button type="submit" class="btn btn-dark mt-3">Registrarse</button>
</form>
</div>
function validateForm() {
let password1 = document.getElementById("password1").value;
let hasNumber = /\d/;
let hasSymbol = /[!#$%&?]/;
if (password1.length < 8) {
Swal.fire("Error", "La contraseña debe tener al menos 8 caracteres.", "error");
return false;
}
if (!hasNumber.test(password1)) {
Swal.fire("Error", "Debe contener al menos un número.", "error");
return false;
}
if (!hasSymbol.test(password1)) {
Swal.fire("Error", "Debe contener un símbolo (!, #, $, %, & o ?).", "error");
return false;
}
Swal.fire("¡Éxito!", "Registro exitoso.", "success");
return true;
}
Bootstrap Icons
For the first time ever, Bootstrap has its own open source SVG icon library, designed to work best with our components and documentation.
Bootstrap Icons are designed to work best with Bootstrap components, but they’ll work in any project. They’re SVGs, so they scale quickly and easily, can be implemented in several ways, and can be styled with CSS.
Get Bootstrap Icons
Official Themes
Take Bootstrap to the next level with premium themes from the official Bootstrap Themes marketplace.
Themes are built on Bootstrap as their own extended frameworks, rich with new components and plugins, documentation, and powerful build tools.
Browse Themes