From 9237dc29edc2a1250d4ff7295917d7fb13920a5e Mon Sep 17 00:00:00 2001 From: Sahil Date: Wed, 21 Jul 2021 17:38:16 +0530 Subject: [PATCH] 'all_task_done' --- authentication/templates/home.html | 15 +++ authentication/templates/register.html | 12 ++ .../templates/registration/login.html | 12 ++ authentication/urls.py | 10 ++ authentication/views.py | 21 ++-- library/settings.py | 2 +- library/urls.py | 2 + store/migrations/0003_auto_20210717_1506.py | 25 ++++ store/migrations/0004_bookrating.py | 25 ++++ store/models.py | 15 ++- store/templates/store/base.html | 14 ++- store/templates/store/book_detail.html | 63 ++++++++-- store/templates/store/index.html | 2 +- store/templates/store/loaned_books.html | 23 +++- store/urls.py | 3 +- store/views.py | 116 +++++++++++++----- 16 files changed, 297 insertions(+), 63 deletions(-) create mode 100644 authentication/templates/home.html create mode 100644 authentication/templates/register.html create mode 100644 authentication/templates/registration/login.html create mode 100644 store/migrations/0003_auto_20210717_1506.py create mode 100644 store/migrations/0004_bookrating.py diff --git a/authentication/templates/home.html b/authentication/templates/home.html new file mode 100644 index 0000000..8fa8216 --- /dev/null +++ b/authentication/templates/home.html @@ -0,0 +1,15 @@ + + + + + + + Library|authentication + + + {% block content %} + + {% endblock %} + + + diff --git a/authentication/templates/register.html b/authentication/templates/register.html new file mode 100644 index 0000000..057f8fe --- /dev/null +++ b/authentication/templates/register.html @@ -0,0 +1,12 @@ +{% extends 'home.html' %} + +{% block content %} +

Create New Account

+
+ {% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} \ No newline at end of file diff --git a/authentication/templates/registration/login.html b/authentication/templates/registration/login.html new file mode 100644 index 0000000..e999034 --- /dev/null +++ b/authentication/templates/registration/login.html @@ -0,0 +1,12 @@ +{% extends 'home.html' %} + +{% block content %} +

Login to account

+
+ {% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} diff --git a/authentication/urls.py b/authentication/urls.py index e69de29..2d8ea29 100644 --- a/authentication/urls.py +++ b/authentication/urls.py @@ -0,0 +1,10 @@ + +from django.urls import path +from . import views +from django.contrib.auth.views import LoginView +urlpatterns = [ + path('',views.indexView, name="home"), + path('login/',LoginView.as_view(),name="login_url"), + path('register/',views.registerView,name="register_url"), + # path('logout/',), +] diff --git a/authentication/views.py b/authentication/views.py index 14dd530..876f87c 100644 --- a/authentication/views.py +++ b/authentication/views.py @@ -1,13 +1,18 @@ -from django.shortcuts import render +from django.shortcuts import render, redirect from django.contrib.auth import login,logout,authenticate +from django.contrib.auth.forms import UserCreationForm # Create your views here. - -def loginView(request): - pass - -def logoutView(request): - pass +def indexView(request): + return render(request,'home.html') def registerView(request): - pass \ No newline at end of file + if request.method == "POST": + form = UserCreationForm(request.POST) + if form.is_valid(): + form.save() + return redirect('login_url') + else: + form = UserCreationForm() + return render(request,'register.html', { 'form': form }) + \ No newline at end of file diff --git a/library/settings.py b/library/settings.py index 9009d3b..168f559 100644 --- a/library/settings.py +++ b/library/settings.py @@ -108,7 +108,7 @@ LANGUAGE_CODE = 'en-us' -TIME_ZONE = 'UTC' +TIME_ZONE = 'Asia/Kolkata' USE_I18N = True diff --git a/library/urls.py b/library/urls.py index 60b7957..dbb12db 100644 --- a/library/urls.py +++ b/library/urls.py @@ -16,10 +16,12 @@ from django.contrib import admin from django.urls import path,include from django.conf.urls.static import static +from django.views.generic import RedirectView from django.conf import settings urlpatterns = [ path('',include('store.urls')), + path('',include('authentication.urls')), path('admin/', admin.site.urls), path('accounts/',include('django.contrib.auth.urls')), ]+static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) diff --git a/store/migrations/0003_auto_20210717_1506.py b/store/migrations/0003_auto_20210717_1506.py new file mode 100644 index 0000000..fd0afaf --- /dev/null +++ b/store/migrations/0003_auto_20210717_1506.py @@ -0,0 +1,25 @@ +# Generated by Django 2.2.1 on 2021-07-17 09:36 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('store', '0002_auto_20190607_1302'), + ] + + operations = [ + migrations.AlterField( + model_name='bookcopy', + name='borrow_date', + field=models.DateField(blank=True, null=True), + ), + migrations.AlterField( + model_name='bookcopy', + name='borrower', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='borrower', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/store/migrations/0004_bookrating.py b/store/migrations/0004_bookrating.py new file mode 100644 index 0000000..e14ae92 --- /dev/null +++ b/store/migrations/0004_bookrating.py @@ -0,0 +1,25 @@ +# Generated by Django 2.2.1 on 2021-07-21 10:16 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('store', '0003_auto_20210717_1506'), + ] + + operations = [ + migrations.CreateModel( + name='BookRating', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('rate', models.FloatField(default=0.0)), + ('book', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.Book')), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/store/models.py b/store/models.py index 17c63a3..8ac9878 100644 --- a/store/models.py +++ b/store/models.py @@ -1,5 +1,6 @@ from django.db import models from django.contrib.auth.models import User + # Create your models here. class Book(models.Model): @@ -8,7 +9,7 @@ class Book(models.Model): genre = models.CharField(max_length=50) description = models.TextField(null=True) mrp = models.PositiveIntegerField() - rating = models.FloatField(default=0.0) + rating = models.PositiveIntegerField(default=0) class Meta: ordering = ('title',) @@ -17,10 +18,20 @@ def __str__(self): return f'{self.title} by {self.author}' +class BookRating(models.Model): + book = models.ForeignKey(Book, on_delete=models.CASCADE) + rate = models.PositiveIntegerField(default=0) + user = models.ForeignKey(User,null=True,blank=True, on_delete=models.SET_NULL) + + def __str__(self): + return f'{self.book}' + + + + class BookCopy(models.Model): book = models.ForeignKey(Book, on_delete=models.CASCADE) borrow_date = models.DateField(null=True, blank=True) - # True status means that the copy is available for issue, False means unavailable status = models.BooleanField(default=False) borrower = models.ForeignKey(User, related_name='borrower', null=True, blank=True, on_delete=models.SET_NULL) diff --git a/store/templates/store/base.html b/store/templates/store/base.html index 64b7a6e..bd33b91 100644 --- a/store/templates/store/base.html +++ b/store/templates/store/base.html @@ -15,21 +15,22 @@
-
+
{% block sidebar %} -
- {% block content %}{% endblock %} + {% block content %} + {% endblock %}
diff --git a/store/templates/store/book_detail.html b/store/templates/store/book_detail.html index 2e4b9e8..43cecec 100644 --- a/store/templates/store/book_detail.html +++ b/store/templates/store/book_detail.html @@ -20,30 +20,67 @@

Title: {{ book.title }}

Rs. {{ book.mrp }}
Available Copies:
{{ num_available }}
+ + +{% if user.is_authenticated %} +
Rate Book:
+
+ + +
+
+ +{% endif %} - + {% endblock %} \ No newline at end of file diff --git a/store/templates/store/index.html b/store/templates/store/index.html index aebaae6..8cf9d04 100644 --- a/store/templates/store/index.html +++ b/store/templates/store/index.html @@ -3,5 +3,5 @@ {% block content %} -

Welcome to the library. This is your homepage.

+

Welcome to the library. This is your homepage.

{% endblock %} \ No newline at end of file diff --git a/store/templates/store/loaned_books.html b/store/templates/store/loaned_books.html index d6f2044..5ca596b 100644 --- a/store/templates/store/loaned_books.html +++ b/store/templates/store/loaned_books.html @@ -37,7 +37,26 @@

Loaned Books list

{% endblock %} \ No newline at end of file diff --git a/store/urls.py b/store/urls.py index 4520334..9d392e8 100644 --- a/store/urls.py +++ b/store/urls.py @@ -8,4 +8,5 @@ path('books/loaned/', viewLoanedBooks, name="view-loaned"), path('books/loan/', loanBookView, name="loan-book"), path('books/return/', returnBookView, name="return-book"), -] + path('book/rate/',rateBookView,name='rate-book'), +] \ No newline at end of file diff --git a/store/views.py b/store/views.py index dc411b9..442691e 100644 --- a/store/views.py +++ b/store/views.py @@ -1,72 +1,86 @@ -from django.shortcuts import render +from django.shortcuts import render,redirect from django.shortcuts import get_object_or_404 from store.models import * from django.contrib.auth.decorators import login_required -from django.http import JsonResponse +from django.http import JsonResponse,Http404,HttpResponse from django.views.decorators.csrf import csrf_exempt +from django.contrib.auth.models import User +from datetime import date +from decimal import Decimal + # Create your views here. def index(request): return render(request, 'store/index.html') + def bookDetailView(request, bid): template_name = 'store/book_detail.html' - context = { - 'book': None, # set this to an instance of the required book - 'num_available': None, # set this to the number of copies of the book available, or 0 if the book isn't available - } - # START YOUR CODE HERE - - + try: + book = Book.objects.get(pk=bid) + except: + raise Http404('No such book!') + else: + num_available = BookCopy.objects.filter(book__exact=book, + status__exact=True).count() + context = { + 'book': book, + 'num_available': num_available, + } return render(request, template_name, context=context) @csrf_exempt def bookListView(request): template_name = 'store/book_list.html' + get_data = request.GET + books = Book.objects.filter( + title__icontains = get_data.get('title',''), + author__icontains = get_data.get('author',''), + genre__icontains = get_data.get('genre',''), + ) context = { - 'books': None, # set this to the list of required books upon filtering using the GET parameters - # (i.e. the book search feature will also be implemented in this view) + 'books': books, } - get_data = request.GET - # START YOUR CODE HERE - - return render(request, template_name, context=context) + + @login_required def viewLoanedBooks(request): template_name = 'store/loaned_books.html' + books = BookCopy.objects.filter(borrower__exact=request.user) context = { - 'books': None, + 'books': books, } ''' The above key 'books' in the context dictionary should contain a list of instances of the BookCopy model. Only those book copies should be included which have been loaned by the user. ''' - # START YOUR CODE HERE - - - return render(request, template_name, context=context) + @csrf_exempt @login_required def loanBookView(request): response_data = { 'message': None, } - ''' - Check if an instance of the asked book is available. - If yes, then set the message to 'success', otherwise 'failure' - ''' - # START YOUR CODE HERE - book_id = None # get the book id from post data - - + if request.method == 'POST': + bid = request.POST.get('bid', None) + bookcopy = BookCopy.objects.filter(book=bid, status=True) + if len(bookcopy) > 0: + bookcopy[0].borrower = request.user + bookcopy[0].borrower_date = date.today() + bookcopy[0].status = False + bookcopy[0].save() + response_data['message'] = 'success' + else: + response_data['message'] = 'not available' return JsonResponse(response_data) + ''' FILL IN THE BELOW VIEW BY YOURSELF. This view will return the issued book. @@ -77,6 +91,50 @@ def loanBookView(request): @csrf_exempt @login_required def returnBookView(request): - pass + if request.method == 'POST': + book_id = request.POST['id'] + try: + book = BookCopy.objects.get(pk=book_id) + except: + return JsonResponse({'message':'No such book'}) + else: + book.status = True + book.borrower = None + book.borrow_date = None + book.save() + return JsonResponse({'message':'success'}) + + + +@csrf_exempt +@login_required +def rateBookView(request): + if request.method == "POST": + bid = request.POST['bid'] + change_rating = Decimal(request.POST['rating']) + if change_rating >= 0 and change_rating <= 10: + try: + book = Book.objects.get(pk=bid) + user = User.objects.get(username = request.user.username) + old_rating = BookRating.objects.filter(book = book, user = user) + old_rating.delete() + objt = BookRating() + objt.user = user + objt.book = book + objt.rate = change_rating + objt.save() + books = BookRating.objects.filter(book = book) + total = 0 + for i in books: + total+=i.rate + book.rating = total/books.count() + book.save() + except: + return JsonResponse({'message':"error"}) + else: + return JsonResponse({'message':'success'}) + else: + return JsonResponse({'message':'Rate from 0-10'}) +