diff --git "a/Django\345\255\246\344\271\240\347\254\224\350\256\260_\346\234\261\346\231\223\350\216\262.pdf" "b/Django\345\255\246\344\271\240\347\254\224\350\256\260_\346\234\261\346\231\223\350\216\262.pdf" new file mode 100644 index 0000000000000000000000000000000000000000..453b99ab5dae985c6c0388be4db078fa22883d30 Binary files /dev/null and "b/Django\345\255\246\344\271\240\347\254\224\350\256\260_\346\234\261\346\231\223\350\216\262.pdf" differ diff --git a/README.md b/README.md index 31bfddb6f1ba67d096c12cd779f2056b4549434b..6ce0e9e2b2ddbd7cccf95f0e54f609b3e11dfc2a 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,9 @@ -# Coding challenge - API - -We'd like to extend this Django REST Framework project (based on the one found -[here](https://github.com/beheshtraya/django_rest_sample)). - -The API stores information about authors, categories and books. - -We'd like to let our API users view library statistics, namely: - - 1. Total number of books owned. - 2. Total cost of all books. - 3. Author with most books. - 4. Category with most books. - -There are a few ways to approach this; feel free to choose one that seems -appropriate, and please explain why you think it's best for us. - -We've also heard of at least one bug in the codebase. Can you try to identify -issues in the existing code, and document how you discovered and fixed the -bugs? - -Also: - - - Please treat all code as production level code. - - Please don’t spend more than 4 hours on this. If time runs short, an - explanation of what you would do given more time is fine. - -## Original `readme.txt` - - > pip install -r requirements.txt - > python manage.py makemigrations - > python manage.py migrate - > python manage.py runserver - -- server will be run on 127.0.0.1:8000 +~~~python +> pip install -r requirements.txt +> python manage.py makemigrations +> python manage.py migrate +> python manage.py runserver 0:8000 + --server will be run on 127.0.0.1:8000 +~~~ + +API接口文档:https://www.showdoc.cc/1945432288894249 \ No newline at end of file diff --git a/db.sqlite3 b/db.sqlite3 index 42db1a76d95f421c660bd03c45f143554cb13386..19deb7d62acc26e632fe42800637c7c2fe6c9d9c 100644 Binary files a/db.sqlite3 and b/db.sqlite3 differ diff --git a/django_rest_sample/settings.py b/django_rest_sample/settings.py index a6dc00d37c5b630e939cc8df79bf81cf1f3b86d5..703149a557ce74421ab0e433b483a4be304a2e5a 100644 --- a/django_rest_sample/settings.py +++ b/django_rest_sample/settings.py @@ -38,7 +38,7 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', 'library_app.apps.LibraryAppConfig', - 'rest_framework' + 'rest_framework', ] MIDDLEWARE = [ diff --git a/django_rest_sample/urls.py b/django_rest_sample/urls.py index 05fb841da371ccc55cbe81f3dacc6687bba81312..7785aa6b71e11c82a54837abf630eb0e981424a6 100644 --- a/django_rest_sample/urls.py +++ b/django_rest_sample/urls.py @@ -14,12 +14,13 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path +from django.urls import path,include from rest_framework import routers +from library_app import add,msg,alter,delete from library_app.views import BookViewSet, CategoryViewSet, AuthorViewSet -router = routers.DefaultRouter() +router = routers.SimpleRouter() router.register(r'books', BookViewSet) router.register(r'categories', CategoryViewSet) router.register(r'authors', AuthorViewSet) @@ -27,4 +28,16 @@ urlpatterns = router.urls urlpatterns += [ path('admin/', admin.site.urls), -] + + path('add_book/', add.add_book), + path('add_category/', add.add_category), + + #path('books/message', msg.count_books), + + path('count_books/', msg.count_books), + path('count_authors/', msg.count_authors), + path('count_categories/', msg.count_categories), + + path('alter_book/', alter.alter_book), + path('delete_book/', delete.del_book), +] \ No newline at end of file diff --git a/library_app/__init__.py b/library_app/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/library_app/add.py b/library_app/add.py new file mode 100644 index 0000000000000000000000000000000000000000..36227928a3ddce275ec9c624081968e926830721 --- /dev/null +++ b/library_app/add.py @@ -0,0 +1,19 @@ +from django.http import JsonResponse + +from .models import Book,Author,Category + +def add_book(request): + aa = Book.objects.get_or_create(title='Oliver Twist',category=Category.objects.filter(id=9).first(),author=Author.objects.filter(id=26).first(),owned=1,price=11.2,publish_date='1938-04-08') + #插入前进行查找,如果没有相同的数据就会添加;如果有就不会 + print(aa) + #采用该方式进行数据的添加 + #会返回一个元组,第一个数据是添加成功的实例; + #第二个数据时True或者False(添加成功为True,失败为False) + #return HttpResponse("插入书籍数据成功!") + return JsonResponse({'code':0,'message':'success'}) + +def add_category(request): + aa = Category.objects.get_or_create(title='Realistic Fiction') + print(aa) + #return HttpResponse("插入类别数据成功!") + return JsonResponse({'code':0,'message':'success'}) diff --git a/library_app/alter.py b/library_app/alter.py new file mode 100644 index 0000000000000000000000000000000000000000..0c668d11c25d32b943fafe4381d44e65c156f031 --- /dev/null +++ b/library_app/alter.py @@ -0,0 +1,9 @@ +from django.http import HttpResponse,JsonResponse + +from .models import Book,Author,Category + +def alter_book(request): + book=Book.objects.get(id = 6) + book.category=Category.objects.get(id=9) + book.save() + return HttpResponse("数据修改成功!") \ No newline at end of file diff --git a/library_app/delete.py b/library_app/delete.py new file mode 100644 index 0000000000000000000000000000000000000000..b4a8f50b7a40f954843976aedfcd442da7ae9e0a --- /dev/null +++ b/library_app/delete.py @@ -0,0 +1,11 @@ +from django.http import HttpResponse,JsonResponse + +from .models import Book,Author,Category + +def del_book(request): + Book.objects.get(id=6).delete() + #get方法得到的是单个实例对象,所以是删除一条数据 + #Book.objects.filter(owned=1).delete() + #filter方法得到owned属性值为1的数据,然后删除这些数据 + #return HttpResponse("删除书籍数据成功!") + return JsonResponse({'code':0,'message':'success'}) \ No newline at end of file diff --git a/library_app/migrations/0001_initial.py b/library_app/migrations/0001_initial.py deleted file mode 100644 index 9ad2d48ee26006350cdea22bc835d62c0ab80a54..0000000000000000000000000000000000000000 --- a/library_app/migrations/0001_initial.py +++ /dev/null @@ -1,45 +0,0 @@ -# Generated by Django 2.0.3 on 2018-04-02 03:21 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='Category', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(blank=True, max_length=100, null=True)), - ], - ), - migrations.CreateModel( - name='Author', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(blank=True, max_length=255, null=True)), - ], - ), - migrations.CreateModel( - name='Book', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(blank=True, max_length=255, null=True)), - ('owned', models.IntegerField()), - ('price', models.FloatField()), - ('publish_date', models.DateField()), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='library_app.Author')), - ], - ), - migrations.AddField( - model_name='book', - name='category', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='library_app.Category'), - ), - ] diff --git a/library_app/migrations/__init__.py b/library_app/migrations/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/library_app/models.py b/library_app/models.py index 4efae69f4620109b96b6cacc7c3809592f8bbc5c..d2a848de7497c117e983ca7bcfca779de6c825b2 100644 --- a/library_app/models.py +++ b/library_app/models.py @@ -10,17 +10,28 @@ class Book(models.Model): publish_date = models.DateField() def __str__(self): + """ + 返回模型的字符串表示 + 我们告诉Django,默认应使用哪个属性来显示有关此模型的信息 + Django调用方法__str__()来显示模型的简单表示 + """ return self.title class Author(models.Model): name = models.CharField(max_length=255, null=True, blank=True) def __str__(self): - return self.name + if self.name: + return self.name + else: + return "作者为空" class Category(models.Model): title = models.CharField(max_length=100, null=True, blank=True) def __str__(self): - return self.title + if self.title: + return self.title + else: + return "类别为空" diff --git a/library_app/msg.py b/library_app/msg.py new file mode 100644 index 0000000000000000000000000000000000000000..88a2153b929529476f5547f53f5d37971e614df6 --- /dev/null +++ b/library_app/msg.py @@ -0,0 +1,56 @@ +from django.http import JsonResponse +import json + +from .models import Book,Author,Category + +def count_books(request): + books = Book.objects.values() + #可以看出查询到的记录对象的输出方式是模型中的__str__格式 + bookslist = list(books) + count = Book.objects.count() + prices=0 + booktitle=[] + + for book in bookslist: + prices += book['price'] + booktitle.append(book['title']) + return JsonResponse({'code':0,'message':'success','data':{'count':count,'prices':prices,'booktitle':booktitle}}) + + +def count_authors(request): + authors = Author.objects.values() + authorslist = list(authors) + max = 0 + author = authorslist[0]['name'] + booktitle = [] + for aut in authorslist: + books = Book.objects.filter(author=aut['id'])#该作者的书籍 + count = books.count()#该作者的书籍数目 + if(count>max): + booktitle = [] + max = count + author = aut['name'] + books = list(books.values()) + for book in books: + booktitle.append(book['title']) + + return JsonResponse({'code':0,'message':'success','data':{'author':author,'booktitle': booktitle}}) + +def count_categories(request): + categories = Category.objects.values() + categorieslist = list(categories) + max = 0 + category = categorieslist[0]['title'] + booktitle = [] + for cat in categorieslist: + books = Book.objects.filter(category=cat['id'])#该类别的书籍 + count = books.count()#该类别的书籍数目 + if(count>max): + booktitle = [] + max = count + category = cat['title'] + books = list(books.values()) + for book in books: + booktitle.append(book['title']) + + return JsonResponse({'code':0,'message':'success','data':{'category':category,'booktitle':booktitle}}) \ No newline at end of file diff --git a/library_app/serializers.py b/library_app/serializers.py index 849aea1f7cfdf51d36afe7743319ac57b0688bc5..add10a3b42d703a90a5af0d1cbb311f4775850c8 100644 --- a/library_app/serializers.py +++ b/library_app/serializers.py @@ -1,9 +1,19 @@ +""" +Serializers allow complex data such as querysets and +model instances to be converted to native Python datatypes +that can then be easily rendered into JSON, XML or other +content types. +""" from rest_framework import serializers from library_app.models import Category, Book, Author - +class CategorySerializer(serializers.ModelSerializer): + class Meta: + model = Category + fields = "__all__"#表示所有字段 + class AuthorSerializer(serializers.ModelSerializer): class Meta: model = Author @@ -16,13 +26,11 @@ class BookReadSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__' + #fields = ("title","owned","category","author") class BookWriteSerializer(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" -class CategorySerializer(serializers.ModelSerializer): - class Meta: - model = Category - fields = "__all__" + diff --git a/library_app/tests.py b/library_app/tests.py index 7ce503c2dd97ba78597f6ff6e4393132753573f6..35edb51d4530d8a9f400c28ffd3326b127390167 100644 --- a/library_app/tests.py +++ b/library_app/tests.py @@ -1,3 +1,3 @@ -from django.test import TestCase - -# Create your tests here. +list = [] +list += 'Hemalt' +print(list) \ No newline at end of file diff --git a/library_app/views.py b/library_app/views.py deleted file mode 100644 index da56ab7fe376dc3d778ee7e3d280b4971270631d..0000000000000000000000000000000000000000 --- a/library_app/views.py +++ /dev/null @@ -1,23 +0,0 @@ -from rest_framework import viewsets - -from library_app.models import Category, Author, Book -from library_app.serializers import CategorySerializer, AuthorSerializer, BookReadSerializer, BookWriteSerializer - - -class BookViewSet(viewsets.ModelViewSet): - queryset = Book.objects.all() - - def get_serializer_class(self): - if self.request.method in ['GET', 'HEAD']: - return BookReadSerializer - else: - return BookWriteSerializer - -class CategoryViewSet(viewsets.ModelViewSet): - queryset = Category.objects.all() - serializer_class = CategorySerializer - - -class AuthorViewSet(viewsets.ModelViewSet): - queryset = Author.objects.all() - serializer_class = AuthorSerializer diff --git a/manage.py b/manage.py old mode 100755 new mode 100644