Skip to content

Commit 057c88b

Browse files
committed
first commit
0 parents  commit 057c88b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+799
-0
lines changed

Diff for: .gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
__pycache__
2+
*.swp
3+
/venv
4+
/.vscode
5+
.DS_Store
6+
env/
7+
.idea

Diff for: README.md

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# branching-django-example
2+
3+
From this repo, you can learn:
4+
5+
- How to connect to TiDB Serverless in Django.
6+
- How to use branching GitHub integration.
7+
8+
## About this repo
9+
10+
This repo is a Django crud example. it consists of 3 small applications:
11+
12+
- books_cbv: Implement CRUD using CBV (Class Based Views).
13+
- books_fbv: Implement CRUD using FBV (Function Based Views).
14+
- books_fbv_user: add user interaction to books_fbv example.
15+
16+
> The repo is based on the [django_crud](https://github.com/rayed/django_crud). Thanks for the author's excellent work.
17+
18+
## Connect to TiDB Serverless in Django
19+
20+
1. clone the code
21+
22+
```
23+
git clone [email protected]:tidbcloud/branching-django-exmaple.git
24+
cd apps
25+
```
26+
27+
2. active virtual environment (Mac)
28+
29+
```
30+
python3 -m venv env
31+
source env/bin/activate
32+
```
33+
34+
For Windows, use env/Scripts/activate.
35+
36+
3. Install the dependencies
37+
38+
```
39+
pip install -r ../requirements.txt
40+
```
41+
42+
4. Fill in the .env file with your TiDB Serverless connection information. You can find the information in the TiDB Serverless console.
43+
44+
```
45+
DB_DATABASE=
46+
DB_USER=
47+
DB_PASSWORD=
48+
DB_HOST=
49+
SSL_CA=
50+
```
51+
52+
5. Migrate the schema
53+
54+
> make sure you have already created the database in TiDB Serverless before running the migrate command.
55+
56+
```
57+
./manage.py migrate
58+
```
59+
60+
6. Run the server
61+
62+
```
63+
./manage.py runserver
64+
```
65+
66+
## Use branching GitHub integration
67+
68+
Assume that you have run the Django project on a TiDB Serverless. Next, you can use the [Branching GitHub integration](https://docs.pingcap.com/tidbcloud/branch-github-integration) to connect the TiDB Serverless to this repo. Then a database branch will be created for every pull request to test the changes before merging the code to the master branch.
69+
70+
This repo has already connected to a TiDB Serverless. Check this [pull request](https://github.com/tidbcloud/branching-django-exmaple/pull/1) to see how we check the migration changes!
71+
72+

Diff for: apps/.env

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
DB_DATABASE=
2+
DB_USER=
3+
DB_PASSWORD=
4+
DB_HOST=
5+
SSL_CA=

Diff for: apps/apps/__init__.py

Whitespace-only changes.

Diff for: apps/apps/settings.py

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
"""
2+
Django settings for zzz project.
3+
4+
Generated by 'django-admin startproject' using Django 2.0.5.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/2.0/topics/settings/
8+
9+
For the full list of settings and their values, see
10+
https://docs.djangoproject.com/en/2.0/ref/settings/
11+
"""
12+
13+
import os
14+
from pathlib import Path
15+
16+
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
17+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
18+
19+
20+
# Quick-start development settings - unsuitable for production
21+
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
22+
23+
# SECURITY WARNING: keep the secret key used in production secret!
24+
SECRET_KEY = 'secret'
25+
26+
# SECURITY WARNING: don't run with debug turned on in production!
27+
DEBUG = True
28+
29+
ALLOWED_HOSTS = []
30+
31+
32+
# Application definition
33+
34+
INSTALLED_APPS = [
35+
'django.contrib.admin',
36+
'django.contrib.auth',
37+
'django.contrib.contenttypes',
38+
'django.contrib.sessions',
39+
'django.contrib.messages',
40+
'django.contrib.staticfiles',
41+
42+
'theme',
43+
'books_cbv',
44+
'books_fbv',
45+
'books_fbv_user',
46+
]
47+
48+
MIDDLEWARE = [
49+
'django.middleware.security.SecurityMiddleware',
50+
'django.contrib.sessions.middleware.SessionMiddleware',
51+
'django.middleware.common.CommonMiddleware',
52+
'django.middleware.csrf.CsrfViewMiddleware',
53+
'django.contrib.auth.middleware.AuthenticationMiddleware',
54+
'django.contrib.messages.middleware.MessageMiddleware',
55+
'django.middleware.clickjacking.XFrameOptionsMiddleware',
56+
]
57+
58+
ROOT_URLCONF = 'apps.urls'
59+
60+
TEMPLATES = [
61+
{
62+
'BACKEND': 'django.template.backends.django.DjangoTemplates',
63+
'DIRS': [],
64+
'APP_DIRS': True,
65+
'OPTIONS': {
66+
'context_processors': [
67+
'django.template.context_processors.debug',
68+
'django.template.context_processors.request',
69+
'django.contrib.auth.context_processors.auth',
70+
'django.contrib.messages.context_processors.messages',
71+
],
72+
},
73+
},
74+
]
75+
76+
WSGI_APPLICATION = 'apps.wsgi.application'
77+
78+
79+
# Database
80+
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
81+
82+
DATABASES = {
83+
'default': {
84+
'ENGINE': 'django.db.backends.mysql',
85+
'NAME': os.environ.get('DB_DATABASE', 'test'),
86+
'HOST': os.environ.get('DB_HOST'),
87+
'PORT': 4000,
88+
'USER': os.environ.get('DB_USER'),
89+
'PASSWORD': os.environ.get('DB_PASSWORD'),
90+
'OPTIONS': {'ssl': {'ca': os.environ.get('SSL_CA')}}
91+
},
92+
}
93+
94+
95+
# Password validation
96+
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
97+
98+
AUTH_PASSWORD_VALIDATORS = [
99+
{
100+
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
101+
},
102+
{
103+
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
104+
},
105+
{
106+
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
107+
},
108+
{
109+
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
110+
},
111+
]
112+
113+
114+
# Internationalization
115+
# https://docs.djangoproject.com/en/2.0/topics/i18n/
116+
117+
LANGUAGE_CODE = 'en-us'
118+
119+
TIME_ZONE = 'UTC'
120+
121+
USE_I18N = True
122+
123+
USE_L10N = True
124+
125+
USE_TZ = True
126+
127+
128+
# Static files (CSS, JavaScript, Images)
129+
# https://docs.djangoproject.com/en/2.0/howto/static-files/
130+
131+
STATIC_URL = '/static/'
132+
STATICFILES_DIRS = [
133+
os.path.join(BASE_DIR, 'static'),
134+
]
135+
#LOGIN_URL = '/accounts/login/'
136+
137+
LOGIN_REDIRECT_URL = '/books_fbv_user/'
138+
LOGOUT_REDIRECT_URL = '/'
139+
140+
141+
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'

Diff for: apps/apps/urls.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from django.urls import include, path
2+
from django.contrib import admin
3+
4+
import theme.views
5+
6+
urlpatterns = [
7+
path('', theme.views.home),
8+
path('books_cbv/', include('books_cbv.urls')),
9+
path('books_fbv/', include('books_fbv.urls')),
10+
path('books_fbv_user/', include('books_fbv_user.urls')),
11+
12+
# Enable built-in authentication views
13+
path('accounts/', include('django.contrib.auth.urls')),
14+
# Enable built-in admin interface
15+
path('admin/', admin.site.urls),
16+
]

Diff for: apps/apps/views.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from django.shortcuts import render

Diff for: apps/apps/wsgi.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
WSGI config for apps project.
3+
4+
It exposes the WSGI callable as a module-level variable named ``application``.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
8+
"""
9+
10+
import os
11+
12+
from django.core.wsgi import get_wsgi_application
13+
14+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "apps.settings")
15+
16+
application = get_wsgi_application()

Diff for: apps/books_cbv/__init__.py

Whitespace-only changes.

Diff for: apps/books_cbv/admin.py

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from django.contrib import admin
2+
from books_cbv.models import Book
3+
4+
admin.site.register(Book)

Diff for: apps/books_cbv/apps.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from django.apps import AppConfig
2+
3+
4+
class BooksCbvConfig(AppConfig):
5+
name = 'books_cbv'

Diff for: apps/books_cbv/migrations/0001_initial.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 2.0.5 on 2018-05-11 15:11
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
initial = True
9+
10+
dependencies = [
11+
]
12+
13+
operations = [
14+
migrations.CreateModel(
15+
name='Book',
16+
fields=[
17+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18+
('name', models.CharField(max_length=200)),
19+
('pages', models.IntegerField()),
20+
],
21+
),
22+
]

Diff for: apps/books_cbv/migrations/__init__.py

Whitespace-only changes.

Diff for: apps/books_cbv/models.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from django.db import models
2+
from django.urls import reverse
3+
4+
5+
class Book(models.Model):
6+
name = models.CharField(max_length=200)
7+
pages = models.IntegerField()
8+
9+
def __str__(self):
10+
return self.name
11+
12+
def get_absolute_url(self):
13+
return reverse('books_cbv:book_edit', kwargs={'pk': self.pk})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{% extends "base.html" %}
2+
3+
{% block content %}
4+
5+
<h2><a href="{% url 'books_cbv:book_list' %}">Books CBV</a>: Delete?</h2>
6+
7+
<form method="post">{% csrf_token %}
8+
Are you sure you want to delete "{{ object }}" ?<br>
9+
<input type="submit" value="Delete" />
10+
</form>
11+
12+
{% endblock %}

Diff for: apps/books_cbv/templates/books_cbv/book_form.html

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{% extends "base.html" %}
2+
3+
{% block content %}
4+
5+
<h2><a href="{% url 'books_cbv:book_list' %}">Books CBV</a>: Edit</h2>
6+
7+
<form method="post">{% csrf_token %}
8+
{{ form.as_p }}
9+
<input type="submit" value="Submit" />
10+
</form>
11+
12+
{% endblock %}

Diff for: apps/books_cbv/templates/books_cbv/book_list.html

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{% extends "base.html" %}
2+
3+
{% block content %}
4+
5+
<h2><a href="{% url 'books_cbv:book_list' %}">Books CBV</a></h2>
6+
7+
<ul>
8+
{% for book in object_list %}
9+
<li>{{ book.name }} ({{ book.pages }} Pages)
10+
<a href="{% url 'books_cbv:book_edit' book.id %}">edit</a>
11+
<a href="{% url 'books_cbv:book_delete' book.id %}">delete</a>
12+
</li>
13+
{% endfor %}
14+
</ul>
15+
16+
<a href="{% url 'books_cbv:book_new' %}">New</a>
17+
18+
{% endblock %}

Diff for: apps/books_cbv/tests.py

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from django.test import TestCase
2+
3+
# Create your tests here.

Diff for: apps/books_cbv/urls.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from django.urls import path
2+
3+
from . import views
4+
5+
app_name = 'books_cbv'
6+
7+
urlpatterns = [
8+
path('', views.BookList.as_view(), name='book_list'),
9+
path('new/', views.BookCreate.as_view(), name='book_new'),
10+
path('edit/<int:pk>/', views.BookUpdate.as_view(), name='book_edit'),
11+
path('delete/<int:pk>/', views.BookDelete.as_view(), name='book_delete'),
12+
]

0 commit comments

Comments
 (0)