Après avoir étudié, j'ai implémenté l'API avec Django REST Framework et essayé de créer une application Todo en utilisant l'API avec Angular 2, alors notez
C'est un état de ce qui a été fait
Django
$ pip install django
$ pip install djangorestframework
$ pip install django-filter
$ pip install django-cors-headers
$ django-admin startproject django_app
$ cd django_app
$ python manage.py startapp to_do
Utilisez simplement un modèle avec uniquement le titre et la date et l'heure de création
django_app/to_do/models.py
from django.db import models
class Todo(models.Model):
title = models.CharField(max_length=140, blank=False)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
django_app/django_app/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'to_do', #ajouter à
]
$ python manage.py makemigrations
$ python manage.py migrate
DB utilise sqlite qui ne nécessite pas de préparation
$ python manage.py createsuperuser
Définissez le nom d'utilisateur, l'adresse e-mail et le mot de passe de manière appropriée
django_app/to_do/admin.py
from django.contrib import admin
from .models import Todo
@admin.register(Todo)
class Todo(admin.ModelAdmin):
pass
python manage.py runserver
Essayez d'accéder et de vous connecter à http: // localhost: 8000 / admin
État avant la connexion
État après connexion
Enregistrons quelques todos de manière appropriée à partir de Add of Todos
django_app/django_app/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'to_do',
'rest_framework', #Postscript
]
Créez serializer.py dans django_app / to_do
django_app/to_do/serializer.py
from rest_framework import serializers
from .models import Todo
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = ('id', 'title', 'created_at')
Modifiez views.py dans django_app / to_do
django_app/to_do/views.py
from django.shortcuts import render
import django_filters
from rest_framework import viewsets, filters
from .models import Todo
from .serializer import TodoSerializer
from rest_framework.decorators import api_view
class TodoViewSet(viewsets.ModelViewSet):
queryset = Todo.objects.all().order_by('-created_at')
serializer_class = TodoSerializer
django_app/django_app/urls.py
from django.conf.urls import url, include //Ajouter inclure
from django.contrib import admin
from to_do.urls import router as to_do_router //Postscript
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/', include(to_do_router.urls)), //Postscript
]
Urls.py côté application n'est pas créé au début, alors créez-le
django_app/to_do/urls.py
from rest_framework import routers
from .views import TodoViewSet
router = routers.DefaultRouter()
router.register(r'todo', TodoViewSet)
$ python manage.py runserver
Accédez à http: // localhost: 8000 / api
Vous devriez voir un écran comme celui-ci
Écrivez les paramètres pour rendre l'API préparée accessible depuis Angular dans settings.py
django_app/django_app/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'to_do',
'rest_framework',
'corsheaders', //Postscript
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.locale.LocaleMiddleware', //Postscript
'corsheaders.middleware.CorsMiddleware', //Postscript
]
~ Omis ~
//Postscript
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
Angular
$ npm install -g @angular/cli
$ ng new ng2app
Ça prend un peu de temps
build
$ cd ng2app
$ ng build
$ ng serve
Essayez d'accéder à http: // localhost: 4200
Il devrait y avoir un écran indiquant que l'application fonctionne!
Tout d'abord, implémentez une fonction telle que simplement acquérir l'API générée par Django REST Framework et l'afficher.
Créez un dossier appelé models dans / ng2app / src / app Créez un fichier appelé todo.model.ts dedans
/ng2app/src/app/models/todo.model.ts
export class Todo {
id: number;
title: string;
}
Dans le modèle de Django, created_at a été défini, mais comme il n'est pas nécessaire sur la face avant, seuls l'id et le titre sont définis.
Créez un dossier appelé services dans / ng2app / src / app Créez un fichier appelé todo.service.ts dedans
Ici, nous allons implémenter le mouvement d'obtention de l'API et de transmission des données.
typescript:/ng2app/src/app/services/todo.service.ts
import { Injectable } from "@angular/core";
import { Http, Headers } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { Todo } from '../models/todo.model';
@Injectable()
export class TodoService {
todo: Todo[] = [];
private Url = `http://127.0.0.1:8000/api/todo/`
private headers = new Headers({'Content-Type': 'application/json'});
constructor(
private http: Http
){}
//Obtenez tous les todos
getAllTodo(): Promise<Todo[]> {
return this.http
.get(this.Url)
.toPromise()
.then(response => response.json() as Todo[])
.catch(this.handleError)
}
}
Créez un dossier appelé composants dans / ng2app / src / app Créez un fichier appelé todo-list.component.ts dedans
typescript:/ng2app/src/app/components/todo-list.component.ts
import { Component,Input } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { TodoService } from '../services/todo.service';
import { Todo } from '../models/todo.model';
@Component({
selector: 'todo-list',
templateUrl: '../templates/todo-list.component.html',
styleUrls: ['../static/todo-list.component.css']
})
export class TodoListComponent {
todos: Todo[] = [];
constructor(
private todoService: TodoService,
){}
ngOnInit(): void {
this.todoService.getAllTodo()
.then(todos => this.todos = todos);
}
}
Créez un dossier appelé templates dans / ng2app / src / app Créez-y todo-list.component.html
html:/ng2app/src/app/templates/todo-list.component.html
<div class="container">
<div class="todo-list row">
<div *ngFor="let todo of todos" class="col-sm-8 col-sm-offset-2">
<div class="panel panel-default">
<div class="panel-body">
<span from="name">{{todo.title}}</span>
</div>
</div>
</div>
</div>
Créez app-routing.module.ts dans / ng2app / src / app
typescript:/ng2app/src/app/app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { TodoListComponent } from './components/todo-list.component';
const routes: Routes = [
{ path: '', component: TodoListComponent }
];
@NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}
Si vous accédez à http: // localhost: 4200
, accédez à TodoListComponent
Modifiez /ng2app/src/app/app.component.ts comme suit
typescript:/ng2app/src/app/app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<h1 class="text-center">
<span class="title">{{ title }}</span>
<p class="sub-title">{{ subtitle }}</p>
</h1>
<router-outlet></router-outlet>
`,
styles: [
'.title { color: #ee6e73;}',
'.sub-title { font-size: small; }'
],
})
export class AppComponent {
title = 'Simple Todo';
subtitle = 'Angular2 + Django Rest Framework'
}
Modifiez /ng2app/src/app/app.module.ts
typescript:/ng2app/src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { TodoListComponent } from './components/todo-list.component';
import { TodoService } from './services/todo.service';
@NgModule({
declarations: [
AppComponent,
TodoListComponent,
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
AppRoutingModule
],
providers: [TodoService],
bootstrap: [AppComponent]
})
export class AppModule { }
Créez un dossier appelé static dans / ng2app / src / app Créer todo-list.component.css Pour le moment, décrivez comme suit
/ng2app/src/app/static/todo-list.component.css
.todo-list {
padding-top: 10px;
}
.todo {
min-height: 130px;
}
.btn-circle {
width: 30px;
height: 30px;
text-align: center;
padding: 6px 0;
font-size: 12px;
line-height: 1.428571429;
border-radius: 15px;
}
.add-todo {
margin-top: 10px;
}
Faites ce qui suit
$ npm install --save bootstrap ng2-bootstrap
Modifiez la partie styles de /ng2app/.angular-cli.json (notez qu'il s'agit d'un fichier caché)
"styles": [
"styles.css",
"../node_modules/bootstrap/dist/css/bootstrap.css", //Postscript
],
Démarrez l'application avec la commande suivante
$ ng serve
Lorsque vous accédez à http: // localhost: 4200 /
, il doit être dans l'état suivant
(Si vous avez enregistré todo depuis Admin de Django)
Ajout de ce qui suit dans TodoService de todo.service.ts
/ng2app/src/services/todo.service.ts
//Comportement au moment de l'ajout
create(todo: Todo): Promise<Todo> {
return this.http
.post(this.Url, JSON.stringify(todo), {headers: this.headers})
.toPromise()
.then(res => res.json())
.catch(this.handleError);
}
//Obtenez l'un des derniers todos ajoutés
getNewTodo(): Promise<Todo> {
return this.http
.get(this.Url+"?limit=1")
.toPromise()
.then(res => res.json().results)
.catch(this.handleError)
}
Ajoutez ce qui suit dans TodoListComponent de todo.component.ts
/ng2app/src/components/todo.component.ts
export class TodoListComponent {
todos: Todo[] = [];
newtodos: Todo[] = []; //Postscript
@Input() todo: Todo = new Todo(); //Postscript
~ Omis ~
//Comportement lorsque le bouton Enregistrer est enfoncé
save(): void {
this.todoService
.create(this.todo)
.then(data => {this.getNewTodo()});
this.todo = new Todo();
}
//Comportement pour appeler le dernier
getNewTodo(): void {
this.todoService
.getNewTodo()
.then(res => {this.pushData(res)});
}
//Pousser les données vers newtodos pour les transmettre au HTML
pushData(data: Todo): void {
this.newtodos.unshift(data);
}
}
Lorsqu'un nouveau todo est ajouté, save () exécute create dans TodoService et POST le nouveau todo. Après cela, exécutez getNewTodo dans TodoService avec getNewTodo () et appelez le dernier (= todo POSTé). Celui appelé est stocké dans newtodos par pushData ().
Modifier todo-list.component.html
/ng2app/src/templates/todo-list.component.html
<div class="container">
<!--d'ici-->
<div class="center">
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<input [(ngModel)]="todo.title"
id="input_text"
type="text"
length="140"
class="form-control add-todo"
placeholder="add-todo"
(keydown.enter)="save()"
>
<button (click)="save()" class="btn btn-success pull-right add-todo">Add</button>
</div>
</div>
</div>
<div class="newtodo-list row" style="margin-top:10px;">
<div *ngFor="let newtodo of newtodos" class="col-sm-8 col-sm-offset-2">
<div class="panel panel-default">
<div class="panel-body">
<span from="name">{{newtodo[0].title}}</span>
</div>
</div>
</div>
</div>
<hr class="col-sm-8 col-sm-offset-2">
<!--Jusque là-->
<div class="todo-list row">
<div *ngFor="let todo of todos" class="col-sm-8 col-sm-offset-2">
<div class="panel panel-default">
<div class="panel-body">
<span from="name">{{todo.title}}</span>
</div>
</div>
</div>
</div>
Démarrez l'application avec la commande suivante
$ ng serve
Il devrait être dans l'état suivant
Vous pouvez ajouter un nouveau todo dans la partie d'entrée
Ajout de ce qui suit dans TodoService de todo.service.ts
/ng2app/src/services/todo.service.ts
//Comportement lors de la suppression
delete(id: number): Promise<void> {
const url = `${this.Url}${id}/`;
return this.http
.delete(url, {headers: this.headers})
.toPromise()
.then(() => null)
.catch(this.handleError);
}
Ajoutez ce qui suit dans TodoListComponent de todo.component.ts
/ng2app/src/components/todo.component.ts
//Comportement lorsque le bouton de suppression est enfoncé
delete(id): void {
this.todoService
.delete(id);
}
Modifier todo-list.component.html
/ng2app/src/templates/todo-list.component.html
<div class="container">
<div class="center">
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<input [(ngModel)]="todo.title"
id="input_text"
type="text"
length="140"
class="form-control add-todo"
placeholder="add-todo"
(keydown.enter)="save()"
>
<button (click)="save()" class="btn btn-success pull-right add-todo">Add</button>
</div>
</div>
</div>
<div class="newtodo-list row" style="margin-top:10px;">
<div *ngFor="let newtodo of newtodos" class="col-sm-8 col-sm-offset-2">
<div [style.display]="!newtodo.hideElement ? 'inline':'none'">
<div class="panel panel-default">
<div class="panel-body">
<span from="name">{{newtodo[0].title}}</span>
<button (click)="delete(newtodo[0].id) || newtodo.hideElement=true"
type="button"
class="btn btn-success btn-circle pull-right"
>
<i class="glyphicon glyphicon-ok"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<hr class="col-sm-8 col-sm-offset-2">
<div class="todo-list row">
<div *ngFor="let todo of todos" class="col-sm-8 col-sm-offset-2">
<div [style.display]="!todo.hideElement ? 'inline':'none'">
<div class="panel panel-default">
<div class="panel-body">
<span from="name">{{todo.title}}</span>
<button (click)="delete(todo.id) || todo.hideElement=true"
type="button"
class="btn btn-success
btn-circle pull-right"
>
<i class="glyphicon glyphicon-ok"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
Ajoutez un bouton, appelez la méthode de suppression lorsque vous appuyez sur le bouton et que l'élément est défini sur display = none (Je ne pense pas que ce soit cool ici alors je veux le réparer)
Démarrez l'application avec la commande suivante
$ ng serve
Il devrait être dans l'état suivant
Vous pouvez supprimer todo avec le bouton à cocher
Ajout de ce qui suit dans TodoService de todo.service.ts
/ng2app/src/services/todo.service.ts
//Comportement au moment de la mise à jour
update(todo: Todo): Promise<Todo> {
const url = `${this.Url}${todo.id}/`;
return this.http
.put(url, JSON.stringify(todo), {headers: this.headers})
.toPromise()
.then(res => res.json())
.catch(this.handleError);
}
Ajoutez ce qui suit dans TodoListComponent de todo.component.ts
/ng2app/src/components/todo.component.ts
//Comportement lors de la mise à jour de todo
update(id: number, title: string): void {
let todo = {
id: id,
title: title
}
this.todoService.update(todo);
}
(Je veux le réparer car ce n'est pas si cool ici non plus)
Modifier todo-list.component.html
/ng2app/src/templates/todo-list.component.html
<div class="container">
<div class="center">
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<input [(ngModel)]="todo.title"
id="input_text"
type="text"
length="140"
class="form-control add-todo"
placeholder="add-todo"
(keydown.enter)="save()"
>
<button (click)="save()" class="btn btn-success pull-right add-todo">Add</button>
</div>
</div>
</div>
<div class="newtodo-list row" style="margin-top:10px;">
<div *ngFor="let newtodo of newtodos" class="col-sm-8 col-sm-offset-2">
<div [style.display]="!newtodo.hideElement ? 'inline':'none'">
<div class="panel panel-default">
<div class="panel-body">
<span *ngIf="!newtodo.isEdit" (click)="newtodo.isEdit=true" from="name">{{newtodo[0].title}}</span>
<input *ngIf="newtodo.isEdit"
(focusout)="newtodo.isEdit=false || update(newtodo[0].id, newtodo[0].title)"
[(ngModel)]="newtodo[0].title"
id="input_text"
type="text"
length="140"
style="border:none; width:70%"
>
<button (click)="delete(newtodo[0].id) || newtodo.hideElement=true"
type="button"
class="btn btn-success btn-circle pull-right"
>
<i class="glyphicon glyphicon-ok"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<hr class="col-sm-8 col-sm-offset-2">
<div class="todo-list row">
<div *ngFor="let todo of todos" class="col-sm-8 col-sm-offset-2">
<div [style.display]="!todo.hideElement ? 'inline':'none'">
<div class="panel panel-default">
<div class="panel-body">
<span *ngIf="!todo.isEdit" (click)="todo.isEdit=true" from="name">{{todo.title}}</span>
<input *ngIf="todo.isEdit"
(focusout)="todo.isEdit=false || update(todo.id, todo.title)"
[(ngModel)]="todo.title"
id="input_text"
type="text"
length="140"
style="border:none; width:70%"
>
<button (click)="delete(todo.id) || todo.hideElement=true"
type="button"
class="btn btn-success
btn-circle pull-right"
>
<i class="glyphicon glyphicon-ok"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
Si vous cliquez sur la chaîne todo, il passera à l'élément d'entrée, et s'il perd le focus de l'entrée, la mise à jour sera exécutée. (C'est aussi cool (ry)
Démarrez l'application avec la commande suivante
$ ng serve
Devrait se comporter comme le gif au début
Je suis un super débutant, donc c'est mieux de faire ça, non? S'il y a quelque chose comme ça, veuillez le signaler.
La source est ici. Pull-Request Bienvenue
Pour le moment, j'ai le sentiment d'intégrer l'authentification des utilisateurs dans cette application et de faire le tour.
[Implémentation d'API à une vitesse explosive à l'aide de Django REST Framework --Qiita] (http://qiita.com/kimihiro_n/items/86e0a9e619720e57ecd8) J'ai créé une application Todo avec Rails 5 + Angular2 + TypeScript. --DC4
Recommended Posts