Tutorial para o projeto negros.dev - A Essência do Django

Overview

Negros Dev

Tutorial para o site negros.dev

Este projeto foi feito com:

Como rodar o projeto?

  • Clone esse repositório.
  • Crie um virtualenv com Python 3.
  • Ative o virtualenv.
  • Instale as dependências.
  • Rode as migrações.
git clone https://github.com/rg3915/django-negros-dev.git
cd django-negros-dev
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python contrib/env_gen.py
python manage.py migrate
python manage.py createsuperuser --username="admin" --email=""

Tutorial

O que é Django?

Segundo Django Brasil,

Django é um framework web de alto nível escrito em Python que estimula o desenvolvimento rápido e limpo.

  • adota o padrão MTV
  • possui ORM
  • admin
  • herança de templates e modelos
  • open source

Documentação oficial Django.

MVC x MTV

  • Model - é o modelo, a camada de abstração do banco de dados, onde acontece o ORM
  • View - é o controlador, onde acontece as regras de negócio e a comunicação entre a base de dados e o navegador
  • Templates - é a camada de apresentação, são as páginas html

image

mtv2.png

ORM

Object Relational Mapper (Mapeamento Objeto Relacional)

Usa orientação a objetos para abstrair as querys do banco de dados.

O exemplo a seguir retorna todos os usuários cujo email termina com gmail.com.

User.objects.filter(email__endswith='gmail.com')

No modelo a seguir Person será o nome da tabela no banco de dados e first_name será o nome do campo.

# models.py
class Person(models.Model):
    first_name = models.CharField('nome', max_length=100, unique=True)

O que é Virtualenv e Requirements?

Virtualenv é um ambiente virtual que isola seu projeto junto com suas dependências.

E requirements é um arquivo (requirements.txt) que lista todas as bibliotecas que você precisa usar no seu projeto, por exemplo:

# requirements.txt
Django==3.1.8
dj-database-url==0.5.0
python-decouple==3.4
django-extensions==3.1.2

Qual é a essência do Django?

  • ORM - abstrair as querys SQL.
  • Admin - O painel de Admin facilita a nossa vida com um CRUD básico.
  • Herança de templates e modelos

Iniciando um projeto

  • Instale o Python na sua versão mais recente.

Crie uma virtualenv

python -m venv .venv

Ative a virtualenv

# Linux
source .venv/bin/activate
# Windows
.venv\Scripts\activate.bat

Instale as dependências

pip install -U pip
pip install Django==3.1.8 dj-database-url python-decouple django-extensions

Importante: crie um arquivo requirements.txt

pip freeze

pip freeze | grep Django==3.1.8 >> requirements.txt
pip freeze | grep dj-database-url >> requirements.txt
pip freeze | grep python-decouple >> requirements.txt
pip freeze | grep django-extensions >> requirements.txt

cat requirements.txt

Criando um .gitignore

Veja no repositório do projeto.

Gere um arquivo .env

Copiar o conteúdo de env_gen.py

https://github.com/rg3915/django-negros-dev/blob/main/contrib/env_gen.py

mkdir contrib
touch contrib/env_gen.py

python contrib/env_gen.py

cat .env

Criando um projeto

django-admin.py startproject myproject .

Criando uma app

cd myproject
python ../manage.py startapp core

Edite o settings.py

# settings.py
INSTALLED_APPS = [
    ...
    'django_extensions',
    'myproject.core',
]

Rodando as migrações para criar um banco de dados local

cd ..
python manage.py migrate

Criando um super usuário

python manage.py createsuperuser

Rodando a aplicação (nível 0)

python manage.py runserver

A aplicação roda na porta 8000.

Projeto mínimo

Veja a estrutura do projeto

├── .gitignore
├── contrib
│   └── env_gen.py
├── db.sqlite3
├── manage.py
├── myproject
│   ├── asgi.py
│   ├── core
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── models.py
│   │   ├── tests.py
│   │   └── views.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── README.md
└── requirements.txt

Nível 1

Editar settings.py

# settings.py
from pathlib import Path

from decouple import Csv, config
from dj_database_url import parse as dburl

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = config('SECRET_KEY')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = config('DEBUG', default=False, cast=bool)

ALLOWED_HOSTS = config('ALLOWED_HOSTS', default=[], cast=Csv())

...

# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases

default_dburl = 'sqlite:///' + str(BASE_DIR / 'db.sqlite3')
DATABASES = {
    'default': config('DATABASE_URL', default=default_dburl, cast=dburl),
}

...

LANGUAGE_CODE = 'pt-br'

TIME_ZONE = 'America/Sao_Paulo'

...

STATIC_ROOT = BASE_DIR.joinpath('staticfiles')

Editar urls.py

# urls.py
from django.contrib import admin
from django.http import HttpResponse
from django.urls import path


def index(request):
    return HttpResponse('<h1>Django Tutorial</h1>')


urlpatterns = [
    path('', index, name='index'),
    path('admin/', admin.site.urls),
]

Nível 2

Editar core/urls.py

touch myproject/core/urls.py
# core/urls.py
from django.urls import path

from .views import index

app_name = 'core'

urlpatterns = [
    path('', index, name='index'),
]

Editar urls.py

# urls.py
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('', include('myproject.core.urls', namespace='core')),
    path('admin/', admin.site.urls),
]

Editar core/views.py

touch myproject/core/views.py
# core/views.py
from django.http import HttpResponse


def index(request):
    return HttpResponse('<h1>Django Tutorial</h1>')

Nível 3

Editar core/views.py

# core/views.py
from django.shortcuts import render


def index(request):
    template_name = 'index.html'
    return render(request, template_name)

Editar core/templates/index.html

mkdir myproject/core/templates
touch myproject/core/templates/index.html
<!-- index -->
<h1>Django Tutorial</h1>
<h2>Negros Dev</h2>

Projeto mais completo

Instalando e usando PostgreSQL

sudo apt-get install -y postgresql-12 postgresql-contrib-12

Criar database

sudo su - postgres
psql -U postgres -c "CREATE ROLE myuser ENCRYPTED PASSWORD 'mypass' LOGIN;"
psql -U postgres -c "CREATE DATABASE mydb OWNER myuser;"

Editar o settings.py

# settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': config('POSTGRES_DB', 'postgres'),
        'USER': config('POSTGRES_USER', 'postgres'),
        'PASSWORD': config('POSTGRES_PASSWORD', ''),
        'HOST': config('DB_HOST', ''),
        'PORT': '5432',
    }
}

Editar o .env

# .env
POSTGRES_DB=
POSTGRES_USER=
POSTGRES_PASSWORD=
DB_HOST=localhost

Instalando psycopg2-binary

django.core.exceptions.ImproperlyConfigured: Error loading psycopg2 module: No module named 'psycopg2'
pip install psycopg2-binary

pip freeze | grep psycopg2-binary >> requirements.txt

Criando um novo app

cd myproject
python ../manage.py startapp expense
cd ..

models.png

Edite o settings.py

# settings.py
INSTALLED_APPS = [
    ...
    'myproject.core',
    'myproject.expense',
]

Editar core/models.py

# core/models.py
from django.db import models


class TimeStampedModel(models.Model):
    created = models.DateTimeField(
        'criado em',
        auto_now_add=True,
        auto_now=False
    )
    modified = models.DateTimeField(
        'modificado em',
        auto_now_add=False,
        auto_now=True
    )

    class Meta:
        abstract = True

Editar expense/models.py

https://docs.djangoproject.com/en/3.2/ref/models/fields/

# expense/models.py
from django.db import models

from myproject.core.models import TimeStampedModel


class Customer(models.Model):
    first_name = models.CharField('nome', max_length=50)
    last_name = models.CharField('sobrenome', max_length=50, null=True, blank=True)  # noqa E501
    email = models.EmailField(null=True, blank=True)

    class Meta:
        ordering = ('first_name',)
        verbose_name = 'cliente'
        verbose_name_plural = 'clientes'

    @property
    def full_name(self):
        return f'{self.first_name} {self.last_name or ""}'.strip()

    def __str__(self):
        return self.full_name


class Expense(TimeStampedModel):
    description = models.CharField('descrição', max_length=100)
    payment_date = models.DateField('data de pagamento', null=True, blank=True)
    customer = models.ForeignKey(
        Customer,
        on_delete=models.SET_NULL,
        verbose_name='pago a',
        related_name='expenses',
        null=True,
        blank=True
    )
    value = models.DecimalField('valor', max_digits=7, decimal_places=2)
    paid = models.BooleanField('pago', default=False)

    class Meta:
        ordering = ('-payment_date',)
        verbose_name = 'despesa'
        verbose_name_plural = 'despesas'

    def __str__(self):
        return self.description

    # def get_absolute_url(self):
    #     return reverse_lazy('_detail', kwargs={'pk': self.pk})

Editar expense/admin.py

# expense/admin.py
from django.contrib import admin

from .models import Customer, Expense

# admin.site.register(Customer)


@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
    list_display = ('__str__', 'email')
    search_fields = ('first_name', 'last_name', 'email')


@admin.register(Expense)
class ExpenseAdmin(admin.ModelAdmin):
    list_display = ('__str__', 'customer', 'value', 'payment_date', 'paid')
    search_fields = ('description', 'customer__first_name', 'customer__last_name')  # noqa E501
    list_filter = ('paid',)
    date_hierarchy = 'payment_date'

Atualizando o banco

Gerar arquivo de migração.

python manage.py makemigrations

Executar a migração.

python manage.py migrate

ORM

python manage.py shell_plus

Criando alguns registros

customers = ['Huguinho', 'Zezinho', 'Luizinho']
for customer in customers:
    Customer.objects.create(first_name=customer)

customers = ['Prático', 'Heitor', 'Cícero']
items = []
for customer in customers:
    obj = Customer(first_name=customer)
    items.append(obj)

Customer.objects.bulk_create(items)

Criar despesas pelo Admin.

Alterando a data das despesas não pagas.

python manage.py shell_plus

# Selecionar as despesas não pagas.
expenses = Expense.objects.filter(paid=False)

# Alterando a data de pagamento para uma data futura.
from datetime import date

future = date(2021, 5, 2)

for expense in expenses:
    expense.payment_date = future

Expense.objects.bulk_update(expenses, ['payment_date'])

Cuidado ao deletar

expense = Expense.objects.get(pk=1)
expense.delete()

Templates

mkdir -p myproject/core/templates/includes

touch myproject/core/templates/base.html
touch myproject/core/templates/includes/nav.html


mkdir -p myproject/core/static/{css,img,js}

touch myproject/core/static/css/style.css
touch myproject/core/static/js/main.js

mkdir -p myproject/expense/templates/expense

touch myproject/expense/templates/expense/expense_{list,detail,form}.html

tree

Editar base.html

<!-- base.html -->
{% load static %}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
  <link rel="shortcut icon" href="https://www.djangoproject.com/favicon.ico">
  <title>Django</title>

  <!-- Bootstrap core CSS -->
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">

  <!-- Font-awesome -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

  <link rel="stylesheet" href="{% static 'css/style.css' %}">

  {% block css %}{% endblock css %}

</head>

<body>
  <div class="container">
    {% include "includes/nav.html" %}
    {% block content %}{% endblock content %}
  </div>

  <!-- jQuery -->
  <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
  <!-- Bootstrap core JS -->
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</body>

</html>

Editar includes/nav.html

<!-- includes/nav.html -->
<!-- https://getbootstrap.com/docs/4.0/examples/starter-template/ -->
<!-- https://github.com/JTruax/bootstrap-starter-template/blob/master/template/start.html -->
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
  <a class="navbar-brand" href="{% url 'core:index' %}">Navbar</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarsExampleDefault">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="{% url 'core:index' %}">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="">Despesas</a>
      </li>
    </ul>
  </div>
</nav>

Editar index.html

<!-- index.html -->
{% extends "base.html" %}

{% block content %}
  <div class="jumbotron">
    <h1>Django Tutorial</h1>
    <a href="https://negros.dev/" target="_blank">negros.dev</a>
  </div>
{% endblock content %}

Editar style.css

cat << EOF > myproject/core/static/css/style.css
body {
  margin-top: 60px;
}

label.required:after {
  content: ' *';
  color: red;
}

.no {
  color: red;
}
EOF

Rodar a aplicação

Editar expense_list.html

<!-- expense_list.html -->
{% extends "base.html" %}

{% block content %}
  Lista de Despesas
{% endblock content %}

Editar expense_detail.html

<!-- expense_detail.html -->
{% extends "base.html" %}

{% block content %}
  Detalhes de Despesa
{% endblock content %}

Editar expense_form.html

<!-- expense_form.html -->
{% extends "base.html" %}

{% block content %}
  Adicionar Despesa
{% endblock content %}

Editar expense/views.py

# expense/views.py
from django.shortcuts import render


def expense_list(request):
    template_name = 'expense/expense_list.html'
    return render(request, template_name)


def expense_detail(request, pk):
    template_name = 'expense/expense_detail.html'
    return render(request, template_name)


def expense_create(request):
    template_name = 'expense/expense_form.html'
    return render(request, template_name)

Editar expense/urls.py

touch myproject/expense/urls.py
# expense/urls.py
from django.urls import path

from myproject.expense import views as v

app_name = 'expense'

urlpatterns = [
    path('', v.expense_list, name='expense_list'),
    path('<int:pk>/', v.expense_detail, name='expense_detail'),
    path('create/', v.expense_create, name='expense_create'),
]

Editar urls.py

# urls.py
...
path('expense/', include('myproject.expense.urls', namespace='expense')),
...

Editar includes/nav.html

...
<a class="nav-link" href="{% url 'expense:expense_list' %}">Despesas</a>
...

Rodar a aplicação e navegar pelas urls.

CRUD

Lista

Editar expense/views.py

# expense/views.py
from .models import Expense


def expense_list(request):
    template_name = 'expense/expense_list.html'
    object_list = Expense.objects.all()
    context = {'object_list': object_list}
    return render(request, template_name, context)

Editar expense_list.html

<!-- expense_list.html -->
{% extends "base.html" %}

{% block content %}
  <h1>
    Lista de Despesas
    <a class="btn btn-primary" href="{% url 'expense:expense_create' %}">Adicionar</a>
  </h1>
  <table class="table">
    <thead>
      <tr>
        <th>Descrição</th>
        <th>Pago a</th>
        <th>Valor</th>
        <th>Data de pagamento</th>
      </tr>
    </thead>
    <tbody>
      {% for object in object_list %}
        <tr>
          <td>
            <a href="{{ object.get_absolute_url }}">{{ object.description }}</a>
          </td>
          <td>{{ object.customer|default:'---' }}</td>
          <td>{{ object.value }}</td>
          <td>{{ object.payment_date|date:'d/m/Y'|default:'---' }}</td>
        </tr>
      {% endfor %}
    </tbody>
  </table>
{% endblock content %}

Editar expense/models.py

# expense/models.py
from django.urls import reverse_lazy

    ...
    def get_absolute_url(self):
        return reverse_lazy('expense:expense_detail', kwargs={'pk': self.pk})

Detalhes

Editar expense_detail.html

<!-- expense_detail.html -->
{% extends "base.html" %}

{% block content %}
  <h1>Detalhes de Despesa</h1>

  <ul>
    <li><b>Descrição:</b> {{ object.description }}</li>
    <li><b>Cliente:</b> {{ object.customer|default:'---' }}</li>
    <li><b>Valor:</b> {{ object.value }}</li>
    <li><b>Data de pagamento:</b> {{ object.payment_date|date:'d/m/Y'|default:'---' }}</li>
  </ul>
{% endblock content %}

Editar expense/views.py

# expense/views.py
def expense_detail(request, pk):
    template_name = 'expense/expense_detail.html'
    _object = Expense.objects.get(pk=pk)
    context = {'object': _object}
    return render(request, template_name, context)

Adicionar

Editar expense_form.html

<!-- expense_form.html -->
{% extends "base.html" %}

{% block content %}
  <h1>Despesa</h1>
  <div class="cols-6">
    <form class="form-horizontal" action="." method="POST" enctype="multipart/form-data">
      <div class="col-sm-6">
        {% csrf_token %}
        {{ form.as_p }}
        <div class="form-group">
          <button type="submit" class="btn btn-primary">Salvar</button>
        </div>
      </div>
    </form>
  </div>
{% endblock content %}

Editar expense/forms.py

touch myproject/expense/forms.py
# expense/forms.py
from django import forms

from .models import Expense


class ExpenseForm(forms.ModelForm):
    required_css_class = 'required'

    payment_date = forms.DateField(
        label='Data de pagamento',
        widget=forms.DateInput(
            format='%Y-%m-%d',
            attrs={
                'type': 'date',
            }),
        input_formats=('%Y-%m-%d',),
        required=False,
    )

    class Meta:
        model = Expense
        # fields = '__all__'
        fields = ('description', 'payment_date', 'customer', 'value')
        # exclude = ('paid',)

    def __init__(self, *args, **kwargs):
        super(ExpenseForm, self).__init__(*args, **kwargs)
        for field_name, field in self.fields.items():
            field.widget.attrs['class'] = 'form-control'

Editar expense/views.py

# expense/views.py
from django.shortcuts import redirect, render

from .forms import ExpenseForm
from .models import Expense


def expense_create(request):
    template_name = 'expense/expense_form.html'
    form = ExpenseForm(request.POST or None)

    if request.method == 'POST':
        if form.is_valid():
            form.save()
            return redirect('expense:expense_list')

    context = {'form': form}
    return render(request, template_name, context)

Editar

Editar expense_list.html

<!-- expense_list.html -->

<th>Ações</th>

  <td>
    <a href="{% url 'expense:expense_update' object.pk %}">
      <i class="fa fa-edit"></i>
    </a>
  </td>

Editar expense/urls.py

# expense/urls.py
...
path('<int:pk>/update/', v.expense_update, name='expense_update'),

Editar expense/views.py

# expense/views.py
def expense_update(request, pk):
    template_name = 'expense/expense_form.html'
    instance = Expense.objects.get(pk=pk)
    form = ExpenseForm(request.POST or None, instance=instance)

    if request.method == 'POST':
        if form.is_valid():
            form.save()
            return redirect('expense:expense_list')

    context = {'form': form}
    return render(request, template_name, context)

Deletar

Editar expense_list.html

<a href="{% url 'expense:expense_delete' object.pk %}" style="padding-left: 7px">
  <i class="fa fa-close no"></i>
</a>

Editar expense/urls.py

# expense/urls.py
...
path('<int:pk>/delete/', v.expense_delete, name='expense_delete'),

Editar expense/views.py

# expense/views.py
def expense_delete(request, pk):
    template_name = 'expense/expense_confirm_delete.html'
    obj = Expense.objects.get(pk=pk)

    if request.method == 'POST':
        obj.delete()
        return redirect('expense:expense_list')

    context = {'object': obj}
    return render(request, template_name, context)

Editar expense/expense_confirm_delete.html

touch myproject/expense/templates/expense/expense_confirm_delete.html
<!-- expense_confirm_delete.html -->
{% extends "base.html" %}

{% block content %}
  <h1>Deletar Despesa</h1>
  <div class="cols-6">
    <form action="." method="POST">
      <div class="col-sm-6">
        {% csrf_token %}
        <p>Deseja deletar {{ object }} ?</p>
        <p>Valor: {{ object.value }}</p>
        <div class="form-group">
          <button type="submit" class="btn btn-primary">Sim</button>
          <a class="btn btn-danger" href="{% url 'expense:expense_list' %}">Não</a>
        </div>
      </div>
    </form>
  </div>
{% endblock content %}

Class Based View

https://ccbv.co.uk/

Editar expense/urls.py

# expense/urls.py
from django.urls import path

from myproject.expense import views as v

app_name = 'expense'

urlpatterns = [
    # path('', v.expense_list, name='expense_list'),
    # path('<int:pk>/', v.expense_detail, name='expense_detail'),
    # path('create/', v.expense_create, name='expense_create'),
    # path('<int:pk>/update/', v.expense_update, name='expense_update'),
    # path('<int:pk>/delete/', v.expense_delete, name='expense_delete'),
    path('', v.ExpenseListView.as_view(), name='expense_list'),
    path('<int:pk>/', v.ExpenseDetailView.as_view(), name='expense_detail'),
    path('create/', v.ExpenseCreateView.as_view(), name='expense_create'),
    path('<int:pk>/update/', v.ExpenseUpdateView.as_view(), name='expense_update'),
    path('<int:pk>/delete/', v.ExpenseDeleteView.as_view(), name='expense_delete'),
]

Editar expense/views.py

# expense/views.py
from django.shortcuts import redirect, render
from django.urls import reverse_lazy
from django.views.generic import (
    CreateView,
    DeleteView,
    DetailView,
    ListView,
    UpdateView
)

...

class ExpenseListView(ListView):
    model = Expense


class ExpenseDetailView(DetailView):
    model = Expense


class ExpenseCreateView(CreateView):
    model = Expense
    form_class = ExpenseForm


class ExpenseUpdateView(UpdateView):
    model = Expense
    form_class = ExpenseForm


class ExpenseDeleteView(DeleteView):
    model = Expense
    success_url = reverse_lazy('expense:expense_list')

Assista: Python-triangulo: Django: FBV vs CBV

Links

Owner
Regis Santos
Python developer and newcomer at VueJS. #django #flask #jQuery #VueJS
Regis Santos
Serve files with Django.

django-downloadview django-downloadview makes it easy to serve files with Django: you manage files with Django (permissions, filters, generation, ...)

Jazzband 328 Dec 07, 2022
Sistema administrador de contranas desarrollador en Django

Sistema Contrasenas Desarrolado en Django Proyecto sistema de administracion de contraseñas, de la experiencia educativa Programacion Segura Descripci

Ibrain Rodriguez Espinoza 1 Sep 24, 2022
WeatherApp - Simple Python Weather App

Weather App Please star this repo if you like ⭐ It's motivates me a lot! Stack A

Ruslan Shvetsov 3 Apr 18, 2022
Simple XML-RPC and JSON-RPC server for modern Django

django-modern-rpc Build an XML-RPC and/or JSON-RPC server as part of your Django project. Major Django and Python versions are supported Main features

Antoine Lorence 82 Dec 04, 2022
A GitHub Action for checking Django migrations

🔍 Django migrations checker A GitHub Action for checking Django migrations About This repository contains a Github Action that checks Django migratio

Oda 5 Nov 15, 2022
Django datatables with htmx.

Django datatables with htmx.

Regis Santos 7 Oct 23, 2022
An airlines clone website with django

abc_airlines is a clone website of an airlines system the way it works is that first you add flights to the website then the users can search flights

milad 1 Nov 16, 2021
Vehicle registration using Python, Django and SQlite3

PythonCrud Cadastro de veículos utilizando Python, Django e SQlite3 Para acessar o deploy no Heroku:

Jorge Thiago 4 May 20, 2022
REST API con Python, Django y MySQL (GET, POST, PUT, DELETE)

django_api_mysql REST API con Python, Django y MySQL (GET, POST, PUT, DELETE) REST API con Python, Django y MySQL (GET, POST, PUT, DELETE)

Andrew 1 Dec 28, 2021
Simple alternative to Doodle polls and scheduling (Python 3, Django 3, JavaScript)

What is jawanndenn? jawanndenn is a simple web application to schedule meetings and run polls, a libre alternative to Doodle. It is using the followin

Sebastian Pipping 169 Jan 06, 2023
Analytics services for Django projects

django-analytical The django-analytical application integrates analytics services into a Django project. Using an analytics service with a Django proj

Jazzband 1.1k Dec 31, 2022
django CMS Association 1.6k Jan 06, 2023
A simple REST API to manage postal addresses, written in Python/Django.

A simple REST API to manage postal addresses, written in Python/Django.

Attila Bagossy 2 Feb 14, 2022
A calendaring app for Django. It is now stable, Please feel free to use it now. Active development has been taken over by bartekgorny.

Django-schedule A calendaring/scheduling application, featuring: one-time and recurring events calendar exceptions (occurrences changed or cancelled)

Tony Hauber 814 Dec 26, 2022
Updates redisearch instance with igdb data used for kimosabe

igdb-pdt Update RediSearch with IGDB games data in the following Format: { "game_slug": { "name": "game_name", "cover": "igdb_coverart_url",

6rotoms 0 Jul 30, 2021
Improved Django model inheritance with automatic downcasting

Polymorphic Models for Django Django-polymorphic simplifies using inherited models in Django projects. When a query is made at the base model, the inh

1.4k Jan 03, 2023
PEP-484 stubs for Django

pep484 stubs for Django This package contains type stubs and a custom mypy plugin to provide more precise static types and type inference for Django f

TypedDjango 1.1k Dec 30, 2022
✋ Auto logout a user after specific time in Django

django-auto-logout Auto logout a user after specific time in Django. Works with Python 🐍 ≥ 3.7, Django 🌐 ≥ 3.0. ✔️ Installation pip install django-a

Georgy Bazhukov 21 Dec 26, 2022
Django CRUD REST API Generator

Django CRUD REST API Generator This is a simple tool that generates a Django REST API with the given models. Specs: Authentication, DRF generic views,

Mehmet Alp Sümer 57 Nov 24, 2022
Plug and play continuous integration with django and jenkins

django-jenkins Plug and play continuous integration with Django and Jenkins Installation From PyPI: $ pip install django-jenkins Or by downloading th

Mikhail Podgurskiy 941 Oct 22, 2022