使用Angular和DRF开发博客应用程序

完成像

    1. 从API中获取文章

 

    1. 以列表形式显示文章标题

 

    点击文章标题后,显示内容

Django的一部分

创建一个Django项目

Django、restframework、corsheaders已经安装。

$ django-admin startproject django_blog
$ cd $_
$ python manage.py startapp blog
$ cd blog
$ touch urls.py
$ touch serializer.py

创建用户的管理界面

$ python manage.py createsuperuser

在设置中添加备注

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',#追加
    'rest_framework',#追加
    'corsheaders',#追加
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',#追加(場所は絶対ここ)
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

#末尾に追加
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True

定义models

from django.db import models

# Create your models here.
class Blog(models.Model):
    title = models.CharField(max_length=140, blank=False)
    text = models.CharField(max_length=1000, blank=False)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title
$ python manage.py makemigrations
$ python manage.py migrate
from django.contrib import admin
from .models import Blog

# Register your models here.
@admin.register(Blog)
class Blog(admin.ModelAdmin):
    pass

创建序列化程序

from rest_framework import serializers
from .models import Blog

class BlogSerializer(serializers.ModelSerializer):
    class Meta:
        model = Blog
        fields = ('id', 'title', 'text', 'created_at')

创建视图

from django.shortcuts import render
from rest_framework import viewsets

from .models import Blog
from .serializer import BlogSerializer

# Create your views here.
class BlogViewSet(viewsets.ModelViewSet):
    queryset = Blog.objects.all()
    serializer_class = BlogSerializer

创建URLs

from rest_framework import routers
from .views import BlogViewSet

router = routers.DefaultRouter()
router.register(r'blog', BlogViewSet)
from django.contrib import admin
from django.urls import path, include

from blog.urls import router as blog_api_router

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(blog_api_router.urls)),
]
スクリーンショット 2020-02-08 15.39.46.png

后端完成。

角部分

创建Angular项目

$ ng new angular-blog

删除欢迎页面

<h1>BLOG</h1>
<router-outlet></router-outlet>

创建组件和服务

$ cd src/app
$ mkdir components
$ cd $_
$ ng g c list
$ ng g c detail
$ cd ..
$ mkdir services
$ cd $_
$ ng g s blog

创建路由

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ListComponent } from './components/list/list.component';
import { DetailComponent } from './components/detail/detail.component';


const routes: Routes = [
  {path: '', component: ListComponent},
  {path: 'detail/:id', component: DetailComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

模块安装

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ListComponent } from './components/list/list.component';
import { DetailComponent } from './components/detail/detail.component';
import { BlogService } from './services/blog.service';

@NgModule({
  declarations: [
    AppComponent,
    ListComponent,
    DetailComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    HttpClientModule
  ],
  providers: [BlogService],
  bootstrap: [AppComponent]
})
export class AppModule { }

创建界面

$ mkdir interfaces
$ cd $_
$ ng g i blog
export interface Blog {
    id: number;
    title: string;
    text: string;
}

创建服务

import { Blog } from './../interfaces/blog';
import { Injectable } from '@angular/core';
import { HttpHeaders, HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable(
)
export class BlogService {
  blog: Blog[] = [];
  private Url = 'http://localhost:8000/api/blog/';
  private headers = new HttpHeaders({
    'Content-Type': 'application/json'
  });

  constructor(
    private http: HttpClient
  ) { }

  getAllBlog(): Observable<any>{
    return this.http.get(this.Url, {headers: this.headers});
  }
}

创建列表组件

<div class="container">
<h1>List</h1>
    <ul class="">
        <li *ngFor="let blog of blogs" class="">
            <a routerLink="detail/{{blog.id}}">
                <span from="name">{{blog.title}}</span>
            </a>
        </li>
    </ul>
</div>
import { BlogService } from './../../services/blog.service';
import { Blog } from './../../interfaces/blog';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {

  blogs: Blog[] = [];

  constructor(
    private blogService: BlogService
  ) { }

  ngOnInit() {
    this.blogService.getAllBlog().subscribe(
      blogs => this.blogs = blogs
    );
  }

}
スクリーンショット 2020-02-08 17.22.23.png

我成功地使用 Angular 将从 API 中获取的帖子显示出来了。

创建详细组件

  getBlog(id: number): Observable<Blog>{
    const url = `${this.Url}${id}`;
    return this.http.get<Blog>(url);
  }
<h1>Detail</h1>
<div *ngIf="blog">
    <h2>{{blog.title}}</h2>
    <p>{{blog.text}}</p>
</div>
<button [routerLink]="['']" routerLinkActive="router-link-active" >
    戻る
</button>
import { Blog } from './../../interfaces/blog';
import { BlogService } from './../../services/blog.service';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-detail',
  templateUrl: './detail.component.html',
  styleUrls: ['./detail.component.css']
})
export class DetailComponent implements OnInit {

  blog: Blog;

  constructor(
    private route: ActivatedRoute,
    private blogService: BlogService
  ) { }

  ngOnInit() {
    this.getBlog();
  }

  getBlog(): void{
    const id = +this.route.snapshot.paramMap.get('id');
    this.blogService.getBlog(id).subscribe(
      blog => this.blog = blog
      );
  }

}
スクリーンショット 2020-02-09 2.06.02.png

通过URL的id查找API数据并能够显示详细信息。

bannerAds