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
Simple application TodoList django with ReactJS

Django & React Django We basically follow the Django REST framework quickstart guide here. Create backend folder with a virtual Python environment: mk

Flavien HUGS 2 Aug 07, 2022
A set of functions related with Django

django-extra-tools Table of contents Installation Quick start Template filters parse_datetime parse_date parse_time parse_duration Aggregation First L

Tomasz Jakub Rup 3 Mar 04, 2020
Automatically deletes old file for FileField and ImageField. It also deletes files on models instance deletion.

Django Cleanup Features The django-cleanup app automatically deletes files for FileField, ImageField and subclasses. When a FileField's value is chang

Ilya Shalyapin 838 Dec 30, 2022
Dynamic Django settings.

Constance - Dynamic Django settings A Django app for storing dynamic settings in pluggable backends (Redis and Django model backend built in) with an

Jazzband 1.5k Jan 07, 2023
A prettier way to see Django requests while developing

A prettier way to see Django requests while developing

Adam Hill 35 Dec 02, 2022
Built from scratch to replicate some of the Django admin functionality and add some more, to serve as an introspective interface for Django and Mongo.

django-mongonaut Info: An introspective interface for Django and MongoDB. Version: 0.2.21 Maintainer: Jazzband (jazzband.co) This Project is Being Mov

Jazzband 238 Dec 26, 2022
Developer-friendly asynchrony for Django

Django Channels Channels augments Django to bring WebSocket, long-poll HTTP, task offloading and other async support to your code, using familiar Djan

Django 5.5k Dec 29, 2022
Projeto onde podes inserir notícias, ver todas as notícias guardas e filtrar por tag. A base de dados usada é o mongoDB.

djangoProject Projeto onde podes inserir notícias, ver todas as notícias guardas e filtrar por tag. A base de dados usada é o mongoDB. packages utiliz

Sofia Rocha 1 Feb 22, 2022
Flashback is an awesome, retro IRC based app built using Django

Flashback Flashback is an awesome, retro IRC based app built using Django (and the Django Rest Framework) for the backend as well as React for the fro

Unloading Gnat 1 Dec 22, 2021
It's the assignment 1 from the Python 2 course, that requires a ToDoApp with authentication using Django

It's the assignment 1 from the Python 2 course, that requires a ToDoApp with authentication using Django

0 Jan 20, 2022
Django-environ allows you to utilize 12factor inspired environment variables to configure your Django application.

Django-environ django-environ allows you to use Twelve-factor methodology to configure your Django application with environment variables. import envi

Daniele Faraglia 2.7k Jan 07, 2023
Full featured redis cache backend for Django.

Redis cache backend for Django This is a Jazzband project. By contributing you agree to abide by the Contributor Code of Conduct and follow the guidel

Jazzband 2.5k Jan 03, 2023
Easy thumbnails for Django

Easy Thumbnails A powerful, yet easy to implement thumbnailing application for Django 1.11+ Below is a quick summary of usage. For more comprehensive

Chris Beaven 1.3k Dec 30, 2022
Use Database URLs in your Django Application.

DJ-Database-URL This simple Django utility allows you to utilize the 12factor inspired DATABASE_URL environment variable to configure your Django appl

Jacob Kaplan-Moss 1.3k Dec 30, 2022
A pickled object field for Django

django-picklefield About django-picklefield provides an implementation of a pickled object field. Such fields can contain any picklable objects. The i

Gintautas Miliauskas 167 Oct 18, 2022
A starter template for building a backend with Django and django-rest-framework using docker with PostgreSQL as the primary DB.

Django-Rest-Template! This is a basic starter template for a backend project with Django as the server and PostgreSQL as the database. About the templ

Akshat Sharma 11 Dec 06, 2022
Django Simple Spam Blocker is blocking spam by regular expression.

Django Simple Spam Blocker is blocking spam by regular expression.

Masahiko Okada 23 Nov 29, 2022
Code coverage measurement for Python

Coverage.py Code coverage testing for Python. Coverage.py measures code coverage, typically during test execution. It uses the code analysis tools and

Ned Batchelder 2.3k Jan 05, 2023
Simply integrate Summernote editor with Django project.

django-summernote Summernote is a simple WYSIWYG editor. django-summernote allows you to embed Summernote into Django very handy. Support admin mixins

Summernote 936 Jan 02, 2023
Simple web site for sharing your short stories and beautiful pictures

Story Contest Simple web site for sharing your short stories and beautiful pictures.(Cloud computing first assignment) Clouds The table below shows cl

Alireza Akhoundi 5 Jan 04, 2023