Nach dem Studium habe ich API mit Django REST Framework implementiert und eine Todo-Anwendung mit API mit Angular2 erstellt
Es ist ein Zustand dessen, was gemacht wurde
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
Verwenden Sie einfach ein Modell mit nur dem Titel sowie dem Erstellungsdatum und der Erstellungszeit
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', #hinzufügen
]
$ python manage.py makemigrations
$ python manage.py migrate
DB verwendet SQLite, für das keine Vorbereitung erforderlich ist
$ python manage.py createsuperuser
Stellen Sie den Benutzernamen, die E-Mail-Adresse und das Passwort entsprechend ein
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
Versuchen Sie, auf "http: // localhost: 8000 / admin" zuzugreifen und sich anzumelden
Vor dem Anmelden angeben
Zustand nach dem Login
Lassen Sie uns einige Aufgaben von Add of Todos entsprechend registrieren
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', #Nachtrag
]
Erstellen Sie serializer.py in 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')
Bearbeiten Sie views.py in 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 //Fügen Sie include hinzu
from django.contrib import admin
from to_do.urls import router as to_do_router //Nachtrag
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/', include(to_do_router.urls)), //Nachtrag
]
Urls.py auf der Anwendungsseite wird zunächst nicht erstellt. Erstellen Sie es daher
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
Greifen Sie auf "http: // localhost: 8000 / api" zu
Sie sollten einen Bildschirm wie diesen sehen
Schreiben Sie die Einstellungen, um die vorbereitete API über Angular zugänglich zu machen, in 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', //Nachtrag
]
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', //Nachtrag
'corsheaders.middleware.CorsMiddleware', //Nachtrag
]
~ Ausgelassen ~
//Nachtrag
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
Angular
$ npm install -g @angular/cli
$ ng new ng2app
Es dauert ein wenig
build
$ cd ng2app
$ ng build
$ ng serve
Versuchen Sie, auf "http: // localhost: 4200" zuzugreifen Es sollte einen Bildschirm geben, auf dem steht, dass die App funktioniert!
Implementieren Sie zunächst eine Funktion, z. B. einfach die vom Django REST Framework generierte API abzurufen und anzuzeigen.
Erstellen Sie einen Ordner mit dem Namen models in / ng2app / src / app Erstellen Sie eine Datei mit dem Namen todo.model.ts
/ng2app/src/app/models/todo.model.ts
export class Todo {
id: number;
title: string;
}
In Djangos Modell wurde created_at definiert, aber da dies auf der Vorderseite nicht erforderlich ist, werden nur ID und Titel definiert.
Erstellen Sie einen Ordner namens services in / ng2app / src / app Erstellen Sie darin eine Datei mit dem Namen todo.service.ts
Hier werden wir die Bewegung implementieren, die API abzurufen und die Daten zu übergeben.
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
){}
//Holen Sie sich alle Aufgaben
getAllTodo(): Promise<Todo[]> {
return this.http
.get(this.Url)
.toPromise()
.then(response => response.json() as Todo[])
.catch(this.handleError)
}
}
Erstellen Sie in / ng2app / src / app einen Ordner mit dem Namen components Erstellen Sie darin eine Datei mit dem Namen todo-list.component.ts
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);
}
}
Erstellen Sie in / ng2app / src / app einen Ordner mit dem Namen templates Erstellen Sie darin 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>
Erstellen Sie app-routing.module.ts in / 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 {}
Wenn Sie auf "http: // localhost: 4200" zugreifen, können Sie zu TodoListComponent wechseln.
Bearbeiten Sie /ng2app/src/app/app.component.ts wie folgt
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'
}
Bearbeiten Sie /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 { }
Erstellen Sie einen Ordner mit dem Namen static in / ng2app / src / app Erstellen Sie todo-list.component.css Beschreiben Sie vorerst wie folgt
/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;
}
Mach Folgendes
$ npm install --save bootstrap ng2-bootstrap
Bearbeiten Sie den Stilteil von /ng2app/.angular-cli.json (beachten Sie, dass es sich um eine versteckte Datei handelt).
"styles": [
"styles.css",
"../node_modules/bootstrap/dist/css/bootstrap.css", //Nachtrag
],
Starten Sie die Anwendung mit dem folgenden Befehl
$ ng serve
Wenn Sie auf "http: // localhost: 4200 /" zugreifen, sollte es sich im folgenden Zustand befinden (Wenn Sie sich bei Admin of Django registriert haben)
Folgendes wurde in TodoService von todo.service.ts hinzugefügt
/ng2app/src/services/todo.service.ts
//Verhalten zum Zeitpunkt der Zugabe
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);
}
//Holen Sie sich eines der neuesten hinzugefügten Aufgaben
getNewTodo(): Promise<Todo> {
return this.http
.get(this.Url+"?limit=1")
.toPromise()
.then(res => res.json().results)
.catch(this.handleError)
}
Fügen Sie in TodoListComponent von todo.component.ts Folgendes hinzu
/ng2app/src/components/todo.component.ts
export class TodoListComponent {
todos: Todo[] = [];
newtodos: Todo[] = []; //Nachtrag
@Input() todo: Todo = new Todo(); //Nachtrag
~ Ausgelassen ~
//Verhalten beim Drücken der Speichern-Taste
save(): void {
this.todoService
.create(this.todo)
.then(data => {this.getNewTodo()});
this.todo = new Todo();
}
//Verhalten, um den neuesten anzurufen
getNewTodo(): void {
this.todoService
.getNewTodo()
.then(res => {this.pushData(res)});
}
//Daten an newtodos senden, um sie an HTML zu übergeben
pushData(data: Todo): void {
this.newtodos.unshift(data);
}
}
Wenn eine neue Aufgabe hinzugefügt wird, führt save () die Erstellung in TodoService aus und POSTs die neue Aufgabe. Führen Sie danach getNewTodo in TodoService mit getNewTodo () aus und rufen Sie das neueste auf (= POSTed todo). Der aufgerufene wird von pushData () in newtodos gespeichert.
Bearbeiten Sie todo-list.component.html
/ng2app/src/templates/todo-list.component.html
<div class="container">
<!--von hier-->
<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">
<!--Bisher-->
<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>
Starten Sie die Anwendung mit dem folgenden Befehl
$ ng serve
Es sollte sich im folgenden Zustand befinden
Sie können im Eingabeteil eine neue Aufgabe hinzufügen
Folgendes wurde in TodoService von todo.service.ts hinzugefügt
/ng2app/src/services/todo.service.ts
//Verhalten beim Löschen
delete(id: number): Promise<void> {
const url = `${this.Url}${id}/`;
return this.http
.delete(url, {headers: this.headers})
.toPromise()
.then(() => null)
.catch(this.handleError);
}
Fügen Sie in TodoListComponent von todo.component.ts Folgendes hinzu
/ng2app/src/components/todo.component.ts
//Verhalten beim Drücken der Löschtaste
delete(id): void {
this.todoService
.delete(id);
}
Bearbeiten Sie 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>
Fügen Sie eine Schaltfläche hinzu, rufen Sie die Löschmethode auf, wenn die Schaltfläche gedrückt wird und das Element auf display = none eingestellt ist (Ich finde es hier nicht cool, also möchte ich es reparieren)
Starten Sie die Anwendung mit dem folgenden Befehl
$ ng serve
Es sollte sich im folgenden Zustand befinden
Sie können Aufgaben mit der Check-Schaltfläche löschen
Folgendes wurde in TodoService von todo.service.ts hinzugefügt
/ng2app/src/services/todo.service.ts
//Verhalten zum Zeitpunkt der Aktualisierung
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);
}
Fügen Sie in TodoListComponent von todo.component.ts Folgendes hinzu
/ng2app/src/components/todo.component.ts
//Verhalten beim Aktualisieren von Aufgaben
update(id: number, title: string): void {
let todo = {
id: id,
title: title
}
this.todoService.update(todo);
}
(Ich möchte es reparieren, weil es auch hier nicht so cool ist)
Bearbeiten Sie 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>
Wenn Sie auf die Aufgabenzeichenfolge klicken, wird zum Eingabeelement gewechselt, und wenn der Fokus der Eingabe verloren geht, wird die Aktualisierung ausgeführt. (Das ist auch cool (ry)
Starten Sie die Anwendung mit dem folgenden Befehl
$ ng serve
Sollte sich wie das GIF am Anfang verhalten
Ich bin ein super Anfänger, also ist es besser, das zu tun, oder? Wenn es so etwas gibt, weisen Sie bitte darauf hin.
Die Quelle ist hier. Pull-Request willkommen
Vorerst habe ich das Gefühl, die Benutzerauthentifizierung in diese Anwendung zu integrieren und dort herumzugehen.
[API mit explosiver Geschwindigkeit mithilfe des Django REST Framework --Qiita implementieren] (http://qiita.com/kimihiro_n/items/86e0a9e619720e57ecd8) Ich habe eine Todo-App mit Rails 5 + Angular2 + TypeScript erstellt. --DC4
Recommended Posts