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

You might also like...
Meta package to combine turbo-django and stimulus-django

Hotwire + Django This repository aims to help you integrate Hotwire with Django 🚀 Inspiration might be taken from @hotwired/hotwire-rails. We are sti

django-reversion is an extension to the Django web framework that provides version control for model instances.

django-reversion django-reversion is an extension to the Django web framework that provides version control for model instances. Requirements Python 3

Django-environ allows you to utilize 12factor inspired environment variables to configure your Django application.
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

Rosetta is a Django application that eases the translation process of your Django projects
Rosetta is a Django application that eases the translation process of your Django projects

Rosetta Rosetta is a Django application that facilitates the translation process of your Django projects. Because it doesn't export any models, Rosett

Cookiecutter Django is a framework for jumpstarting production-ready Django projects quickly.
Cookiecutter Django is a framework for jumpstarting production-ready Django projects quickly.

Cookiecutter Django Powered by Cookiecutter, Cookiecutter Django is a framework for jumpstarting production-ready Django projects quickly. Documentati

Django project starter on steroids: quickly create a Django app AND generate source code for data models + REST/GraphQL APIs (the generated code is auto-linted and has 100% test coverage).

Create Django App 💛 We're a Django project starter on steroids! One-line command to create a Django app with all the dependencies auto-installed AND

django-quill-editor makes Quill.js easy to use on Django Forms and admin sites
django-quill-editor makes Quill.js easy to use on Django Forms and admin sites

django-quill-editor django-quill-editor makes Quill.js easy to use on Django Forms and admin sites No configuration required for static files! The ent

A Django chatbot that is capable of doing math and searching Chinese poet online. Developed with django, channels, celery and redis.

Django Channels Websocket Chatbot A Django chatbot that is capable of doing math and searching Chinese poet online. Developed with django, channels, c

A handy tool for generating Django-based backend projects without coding. On the other hand, it is a code generator of the Django framework.
A handy tool for generating Django-based backend projects without coding. On the other hand, it is a code generator of the Django framework.

Django Sage Painless The django-sage-painless is a valuable package based on Django Web Framework & Django Rest Framework for high-level and rapid web

Owner
Regis Santos
Python developer and newcomer at VueJS. #django #flask #jQuery #VueJS
Regis Santos
Simpliest django(uvicorn)+postgresql+nginx docker-compose (ready for production and dev)

simpliest django(uvicorn)+postgresql+nginx docker-compose (ready for production and dev) To run in production: docker-compose up -d Site available on

Artyom Lisovskii 1 Dec 16, 2021
Wagtail - Vue - Django : The initial environment of full-stack local dev web app with wagtail and vue

Wagtail - Vue - Django : The initial environment of full-stack local dev web app with wagtail and vue. A demo to show how to use .vue files inside django app.

Quang PHAM 2 Oct 20, 2022
Atualizando o projeto APIs REST Django REST 2.0

APIs REST Django REST 3.0-KevinSoffa Atualização do projeto APIs REST Django REST 2.0-Kevin Soffa Melhorando e adicionando funcionalidades O que já fo

Kevin Soffa 2 Dec 13, 2022
Projeto Crud Django and Mongo

Projeto-Crud_Django_and_Mongo Configuração para rodar o projeto Download Project

Samuel Fernandes Oliveira 2 Jan 24, 2022
demo project for django channels tutorial

django_channels_chat_official_tutorial demo project for django channels tutorial code from tutorial page: https://channels.readthedocs.io/en/stable/tu

lightsong 1 Oct 22, 2021
Django Girls Tutorial Workshop

Django Girls Tutorial Workshop A log of activities during the workshop. this is an H2 git remote add origin https://github.com/ahuimanu/django_girls_t

Jeffry Babb 1 Oct 27, 2021
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
Website desenvolvido em Django para gerenciamento e upload de arquivos (.pdf).

Website para Gerenciamento de Arquivos Features Esta é uma aplicação full stack web construída para desenvolver habilidades com o framework Django. O

Alinne Grazielle 8 Sep 22, 2022
Agenda feita usando o django para adicionar eventos

Agenda de Eventos Projeto Agenda com Django Inicio O projeto foi iniciado no Django, usando o models.py foi adicionado os dados dos eventos e feita as

Bruno Fernandes 1 Apr 14, 2022
Django URL Shortener is a Django app to to include URL Shortening feature in your Django Project

Django URL Shortener Django URL Shortener is a Django app to to include URL Shortening feature in your Django Project Install this package to your Dja

Rishav Sinha 4 Nov 18, 2021