diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 29bc185..7fc4355 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,7 +2,7 @@ I have completed the following tasks -- [ ] Stage 1 -- [ ] Stage 2 -- [ ] Stage 3 -- [ ] Stage 4 +- [x] Stage 1 +- [x] Stage 2 +- [x] Stage 3 +- [x] Stage 4 diff --git a/authentication/admin.py b/authentication/admin.py index 8c38f3f..e69de29 100644 --- a/authentication/admin.py +++ b/authentication/admin.py @@ -1,3 +0,0 @@ -from django.contrib import admin - -# Register your models here. diff --git a/authentication/models.py b/authentication/models.py index 71a8362..e69de29 100644 --- a/authentication/models.py +++ b/authentication/models.py @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/authentication/templates/registration/login.html b/authentication/templates/registration/login.html new file mode 100755 index 0000000..2d9d3f1 --- /dev/null +++ b/authentication/templates/registration/login.html @@ -0,0 +1,15 @@ +{% extends "store/base.html" %} + +{% block content %} +

Login here :

+
+ {% csrf_token %} + {# A more "HTML" way of creating the login form#} + + + + + +
{%if error%}{{error}}{%endif%}
+
+{% endblock %} \ No newline at end of file diff --git a/authentication/templates/registration/logout.html b/authentication/templates/registration/logout.html new file mode 100755 index 0000000..eddbbf1 --- /dev/null +++ b/authentication/templates/registration/logout.html @@ -0,0 +1,6 @@ +{% extends "store/base.html" %} + +{% block content %} +

Logged Out

+

You have been logged out. You may log back in.

+{% endblock %} \ No newline at end of file diff --git a/authentication/templates/registration/register.html b/authentication/templates/registration/register.html new file mode 100755 index 0000000..89bd841 --- /dev/null +++ b/authentication/templates/registration/register.html @@ -0,0 +1,34 @@ +{% extends "store/base.html" %} + +{% block content %} +

Sign up

+
+ {% csrf_token %} +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + {% if msg %}{% endif %} +
+{% endblock %} \ No newline at end of file diff --git a/authentication/urls.py b/authentication/urls.py index e69de29..65ba823 100644 --- a/authentication/urls.py +++ b/authentication/urls.py @@ -0,0 +1,8 @@ +from django.urls import path +from authentication.views import * + +urlpatterns = [ + path('login/', loginView, name="login"), + path('logout/', logoutView, name="logout" ), + path('register/', registerView, name="register" ), +] \ No newline at end of file diff --git a/authentication/views.py b/authentication/views.py index 14dd530..a6b947e 100644 --- a/authentication/views.py +++ b/authentication/views.py @@ -1,13 +1,59 @@ -from django.shortcuts import render +from django.shortcuts import render,redirect from django.contrib.auth import login,logout,authenticate +from django.http import HttpResponseRedirect, HttpResponse +from django.urls import reverse +from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User # Create your views here. def loginView(request): - pass - + if request.method == 'POST': + username = request.POST.get('username') + password = request.POST.get('password') + user = authenticate(username=username, password=password) + if user: + login(request,user) + return redirect('/') + else: + return render(request, 'registration/login.html', {'error':"Invalid UserName or Password"}) + else: + return render(request, 'registration/login.html', {}) +@login_required def logoutView(request): - pass + logout(request) + return redirect('/') def registerView(request): - pass \ No newline at end of file + if request.method=="POST": + try: + username=request.POST['username'] + password1=request.POST['password1'] + password2=request.POST['password2'] + firstname=request.POST['firstname'] + lastname=request.POST['lastname'] + email=request.POST['email'] + except: + return render(request,'registration/register.html',{'msg':"Fill All The Fields"}) + if password1 != password2: + return render(request, 'registration/register.html', { 'msg': "Passwords not matching" }) + try: + user = User.objects.create_user( + username = username, + first_name = firstname, + last_name = lastname, + email = email, + password = password1 + ) + user.save() + except: + return render(request, 'registration/register.html', { 'msg': "Username already exists" }) + user = authenticate(request, username=username, password=password1) + if user is not None: + login(request, user) + return redirect('/') + else: + return render(request, 'registration/register.html', { 'msg': "User created Successfully" }) + else: + return render(request, 'registration/register.html') + diff --git a/library/settings.py b/library/settings.py index 9009d3b..a888e56 100644 --- a/library/settings.py +++ b/library/settings.py @@ -123,7 +123,6 @@ STATIC_URL = '/static/' STATIC_ROOT=os.path.join(BASE_DIR,'staticfiles/') LOGIN_REDIRECT_URL='/' -LOGOUT_REDIRECT_URL = '/' # Activate Django-Heroku. django_heroku.settings(locals()) diff --git a/library/urls.py b/library/urls.py index 60b7957..a6605ce 100644 --- a/library/urls.py +++ b/library/urls.py @@ -21,5 +21,5 @@ urlpatterns = [ path('',include('store.urls')), path('admin/', admin.site.urls), - path('accounts/',include('django.contrib.auth.urls')), + path('',include('authentication.urls')), ]+static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) diff --git a/myvenv/Scripts/Activate.ps1 b/myvenv/Scripts/Activate.ps1 new file mode 100755 index 0000000..ce5be89 --- /dev/null +++ b/myvenv/Scripts/Activate.ps1 @@ -0,0 +1,51 @@ +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + if (Test-Path function:_OLD_VIRTUAL_PROMPT) { + copy-item function:_OLD_VIRTUAL_PROMPT function:prompt + remove-item function:_OLD_VIRTUAL_PROMPT + } + + if (Test-Path env:_OLD_VIRTUAL_PYTHONHOME) { + copy-item env:_OLD_VIRTUAL_PYTHONHOME env:PYTHONHOME + remove-item env:_OLD_VIRTUAL_PYTHONHOME + } + + if (Test-Path env:_OLD_VIRTUAL_PATH) { + copy-item env:_OLD_VIRTUAL_PATH env:PATH + remove-item env:_OLD_VIRTUAL_PATH + } + + if (Test-Path env:VIRTUAL_ENV) { + remove-item env:VIRTUAL_ENV + } + + if (!$NonDestructive) { + # Self destruct! + remove-item function:deactivate + } +} + +deactivate -nondestructive + +$env:VIRTUAL_ENV="C:\Users\gupta\csoc-2020-task-2\myvenv" + +if (! $env:VIRTUAL_ENV_DISABLE_PROMPT) { + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT {""} + copy-item function:prompt function:_OLD_VIRTUAL_PROMPT + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green '(myvenv) ' + _OLD_VIRTUAL_PROMPT + } +} + +# Clear PYTHONHOME +if (Test-Path env:PYTHONHOME) { + copy-item env:PYTHONHOME env:_OLD_VIRTUAL_PYTHONHOME + remove-item env:PYTHONHOME +} + +# Add the venv to the PATH +copy-item env:PATH env:_OLD_VIRTUAL_PATH +$env:PATH = "$env:VIRTUAL_ENV\Scripts;$env:PATH" diff --git a/myvenv/Scripts/activate b/myvenv/Scripts/activate new file mode 100755 index 0000000..603c7a4 --- /dev/null +++ b/myvenv/Scripts/activate @@ -0,0 +1,76 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="C:\Users\gupta\csoc-2020-task-2\myvenv" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/Scripts:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + if [ "x(myvenv) " != x ] ; then + PS1="(myvenv) ${PS1:-}" + else + if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" + else + PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" + fi + fi + export PS1 +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r +fi diff --git a/myvenv/Scripts/activate.bat b/myvenv/Scripts/activate.bat new file mode 100755 index 0000000..e2cfb32 --- /dev/null +++ b/myvenv/Scripts/activate.bat @@ -0,0 +1,33 @@ +@echo off + +rem This file is UTF-8 encoded, so we need to update the current code page while executing it +for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( + set _OLD_CODEPAGE=%%a +) +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" 65001 > nul +) + +set VIRTUAL_ENV=C:\Users\gupta\csoc-2020-task-2\myvenv + +if not defined PROMPT set PROMPT=$P$G + +if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT% +if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% + +set _OLD_VIRTUAL_PROMPT=%PROMPT% +set PROMPT=(myvenv) %PROMPT% + +if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% +set PYTHONHOME= + +if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH% +if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH% + +set PATH=%VIRTUAL_ENV%\Scripts;%PATH% + +:END +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul + set _OLD_CODEPAGE= +) diff --git a/myvenv/Scripts/deactivate.bat b/myvenv/Scripts/deactivate.bat new file mode 100755 index 0000000..313c079 --- /dev/null +++ b/myvenv/Scripts/deactivate.bat @@ -0,0 +1,21 @@ +@echo off + +if defined _OLD_VIRTUAL_PROMPT ( + set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) +set _OLD_VIRTUAL_PROMPT= + +if defined _OLD_VIRTUAL_PYTHONHOME ( + set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" + set _OLD_VIRTUAL_PYTHONHOME= +) + +if defined _OLD_VIRTUAL_PATH ( + set "PATH=%_OLD_VIRTUAL_PATH%" +) + +set _OLD_VIRTUAL_PATH= + +set VIRTUAL_ENV= + +:END diff --git a/myvenv/Scripts/django-admin.exe b/myvenv/Scripts/django-admin.exe new file mode 100755 index 0000000..a87b794 Binary files /dev/null and b/myvenv/Scripts/django-admin.exe differ diff --git a/myvenv/Scripts/django-admin.py b/myvenv/Scripts/django-admin.py new file mode 100755 index 0000000..611bb38 --- /dev/null +++ b/myvenv/Scripts/django-admin.py @@ -0,0 +1,5 @@ +#!c:\users\gupta\csoc-2020-task-2\myvenv\scripts\python.exe +from django.core import management + +if __name__ == "__main__": + management.execute_from_command_line() diff --git a/myvenv/Scripts/easy_install-3.7.exe b/myvenv/Scripts/easy_install-3.7.exe new file mode 100755 index 0000000..4c3932a Binary files /dev/null and b/myvenv/Scripts/easy_install-3.7.exe differ diff --git a/myvenv/Scripts/easy_install.exe b/myvenv/Scripts/easy_install.exe new file mode 100755 index 0000000..4c3932a Binary files /dev/null and b/myvenv/Scripts/easy_install.exe differ diff --git a/myvenv/Scripts/epylint.exe b/myvenv/Scripts/epylint.exe new file mode 100755 index 0000000..501933f Binary files /dev/null and b/myvenv/Scripts/epylint.exe differ diff --git a/myvenv/Scripts/gunicorn.exe b/myvenv/Scripts/gunicorn.exe new file mode 100755 index 0000000..1e13be8 Binary files /dev/null and b/myvenv/Scripts/gunicorn.exe differ diff --git a/myvenv/Scripts/isort.exe b/myvenv/Scripts/isort.exe new file mode 100755 index 0000000..89379e3 Binary files /dev/null and b/myvenv/Scripts/isort.exe differ diff --git a/myvenv/Scripts/pip.exe b/myvenv/Scripts/pip.exe new file mode 100755 index 0000000..e1413c1 Binary files /dev/null and b/myvenv/Scripts/pip.exe differ diff --git a/myvenv/Scripts/pip3.7.exe b/myvenv/Scripts/pip3.7.exe new file mode 100755 index 0000000..e1413c1 Binary files /dev/null and b/myvenv/Scripts/pip3.7.exe differ diff --git a/myvenv/Scripts/pip3.exe b/myvenv/Scripts/pip3.exe new file mode 100755 index 0000000..e1413c1 Binary files /dev/null and b/myvenv/Scripts/pip3.exe differ diff --git a/myvenv/Scripts/pylint.exe b/myvenv/Scripts/pylint.exe new file mode 100755 index 0000000..2df1094 Binary files /dev/null and b/myvenv/Scripts/pylint.exe differ diff --git a/myvenv/Scripts/pyreverse.exe b/myvenv/Scripts/pyreverse.exe new file mode 100755 index 0000000..127d1c1 Binary files /dev/null and b/myvenv/Scripts/pyreverse.exe differ diff --git a/myvenv/Scripts/python.exe b/myvenv/Scripts/python.exe new file mode 100755 index 0000000..1903f98 Binary files /dev/null and b/myvenv/Scripts/python.exe differ diff --git a/myvenv/Scripts/pythonw.exe b/myvenv/Scripts/pythonw.exe new file mode 100755 index 0000000..12464fc Binary files /dev/null and b/myvenv/Scripts/pythonw.exe differ diff --git a/myvenv/Scripts/sqlformat.exe b/myvenv/Scripts/sqlformat.exe new file mode 100755 index 0000000..8d61939 Binary files /dev/null and b/myvenv/Scripts/sqlformat.exe differ diff --git a/myvenv/Scripts/symilar.exe b/myvenv/Scripts/symilar.exe new file mode 100755 index 0000000..ffb50a4 Binary files /dev/null and b/myvenv/Scripts/symilar.exe differ diff --git a/myvenv/Scripts/wheel.exe b/myvenv/Scripts/wheel.exe new file mode 100755 index 0000000..892ee42 Binary files /dev/null and b/myvenv/Scripts/wheel.exe differ diff --git a/myvenv/pyvenv.cfg b/myvenv/pyvenv.cfg new file mode 100755 index 0000000..d3bfc2d --- /dev/null +++ b/myvenv/pyvenv.cfg @@ -0,0 +1,3 @@ +home = C:\Users\gupta\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0 +include-system-site-packages = false +version = 3.7.7 diff --git a/store/admin.py b/store/admin.py index 144f0f1..6a6b006 100644 --- a/store/admin.py +++ b/store/admin.py @@ -2,5 +2,16 @@ from store.models import * # Register your models here. -admin.site.register(Book) -admin.site.register(BookCopy) +#admin.site.register(Book) +#admin.site.register(BookCopy) +@admin.register(Book) +class BookAdmin(admin.ModelAdmin): + list_display = ('title', 'author', 'genre') + +# Register the Admin classes for BookInstance using the decorator +@admin.register(BookCopy) +class BookInstanceAdmin(admin.ModelAdmin): + list_filter = ('status', 'borrow_date') + list_display = ('book','status', 'borrow_date') + +admin.site.register(BookRating) diff --git a/store/migrations/0003_auto_20200502_0222.py b/store/migrations/0003_auto_20200502_0222.py new file mode 100755 index 0000000..27fed5c --- /dev/null +++ b/store/migrations/0003_auto_20200502_0222.py @@ -0,0 +1,31 @@ +# Generated by Django 3.0.5 on 2020-05-01 20:52 + +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', '0002_auto_20190607_1302'), + ] + + operations = [ + migrations.AddField( + model_name='book', + name='ratinguser', + field=models.FloatField(default=0.0), + ), + 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_auto_20200502_0357.py b/store/migrations/0004_auto_20200502_0357.py new file mode 100755 index 0000000..5d3ecbb --- /dev/null +++ b/store/migrations/0004_auto_20200502_0357.py @@ -0,0 +1,26 @@ +# Generated by Django 3.0.5 on 2020-05-01 22:27 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('store', '0003_auto_20200502_0222'), + ] + + operations = [ + migrations.RemoveField( + model_name='book', + name='ratinguser', + ), + migrations.CreateModel( + name='BookRating', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('ratinguser', models.FloatField(default=0.0)), + ('book', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.Book')), + ], + ), + ] diff --git a/store/migrations/0005_bookrating_user.py b/store/migrations/0005_bookrating_user.py new file mode 100755 index 0000000..781e3e6 --- /dev/null +++ b/store/migrations/0005_bookrating_user.py @@ -0,0 +1,21 @@ +# Generated by Django 3.0.5 on 2020-05-01 22:31 + +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', '0004_auto_20200502_0357'), + ] + + operations = [ + migrations.AddField( + model_name='bookrating', + name='user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='user', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/store/models.py b/store/models.py index 17c63a3..4b601e9 100644 --- a/store/models.py +++ b/store/models.py @@ -9,6 +9,7 @@ class Book(models.Model): description = models.TextField(null=True) mrp = models.PositiveIntegerField() rating = models.FloatField(default=0.0) + class Meta: ordering = ('title',) @@ -30,3 +31,9 @@ def __str__(self): else: return f'{self.book.title} - Available' +class BookRating(models.Model): + user=models.ForeignKey(User, related_name='user', null=True, blank=True, on_delete=models.SET_NULL) + book = models.ForeignKey(Book, on_delete=models.CASCADE) + ratinguser = models.FloatField(default=0) + def __str__(self): + return f'{self.book.title}' \ No newline at end of file diff --git a/store/templates/store/base.html b/store/templates/store/base.html index 64b7a6e..1fb6c8b 100644 --- a/store/templates/store/base.html +++ b/store/templates/store/base.html @@ -29,7 +29,8 @@
  • My Borrowed
  • Logout
  • {% else %} - +
  • Login
  • +
  • Register
  • {% endif %} diff --git a/store/templates/store/book_detail.html b/store/templates/store/book_detail.html index 2e4b9e8..cf822ff 100644 --- a/store/templates/store/book_detail.html +++ b/store/templates/store/book_detail.html @@ -14,15 +14,47 @@

    Title: {{ book.title }}

    {{ book.author }}
    Description:
    {{ book.description }}
    -
    Rating:
    +
    Average Rating:
    {{ book.rating }}
    MRP:
    Rs. {{ book.mrp }}
    Available Copies:
    -
    {{ num_available }}
    +
    {{ num_available }}
    +
    Rating Given By You:
    +
    {% endblock %} \ No newline at end of file diff --git a/store/urls.py b/store/urls.py index 4520334..df3f2b0 100644 --- a/store/urls.py +++ b/store/urls.py @@ -4,8 +4,9 @@ urlpatterns = [ path('', index, name="index"), path('books/', bookListView, name="book-list"), - path('book//', bookDetailView, name='book-detail' ), + path('book//', bookDetailView, name="book-detail" ), path('books/loaned/', viewLoanedBooks, name="view-loaned"), path('books/loan/', loanBookView, name="loan-book"), path('books/return/', returnBookView, name="return-book"), + path('book/rating/', bookRatingView, name="book-rating" ), ] diff --git a/store/views.py b/store/views.py index dc411b9..4f6bc68 100644 --- a/store/views.py +++ b/store/views.py @@ -4,6 +4,10 @@ from django.contrib.auth.decorators import login_required from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt +from django.utils import timezone +import datetime + + # Create your views here. @@ -12,21 +16,61 @@ def index(request): def bookDetailView(request, bid): template_name = 'store/book_detail.html' + book1=Book.objects.get(pk=bid) + num_available=BookCopy.objects.filter(status__exact=True,book__exact=book1).count() + user_rating=0.0 + if(request.user.is_authenticated): + value= BookRating.objects.filter(book__exact=book1,user__exact=request.user) + user_rating=0 + if(value.count()>0): + user_rating=BookRating.objects.filter(book__exact=book1,user__exact=request.user).get().ratinguser + 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 + 'book': book1, # set this to an instance of the required book + 'num_available':num_available, # set this to the number of copies of the book available, or 0 if the book isn't available + 'user_rating':user_rating, } - # START YOUR CODE HERE - - return render(request, template_name, context=context) +@csrf_exempt +def bookRatingView(request): + template_name= template_name = 'store/book_detail.html' + book_id = request.POST.get("bid") + rating_value = request.POST.get("rating") + book1=Book.objects.get(pk=book_id) + value= BookRating.objects.filter(book__exact=book1,user__exact=request.user) + if(value.count()>0): + currentuserRating= BookRating.objects.filter(book__exact=book1,user__exact=request.user).get() + #print(currentuserRating[0].ratinguser) + currentuserRating.ratinguser=rating_value + currentuserRating.save() + else: + BookRating.objects.create(user=request.user,book=book1,ratinguser=rating_value) + userRating= BookRating.objects.filter(book__exact=book1) + length=len(userRating) + avg_rating=0 + for each in userRating: + avg_rating+=each.ratinguser/length + book1.rating=avg_rating + book1.save() + message="success" + response_data = { + 'message': message, + } + return JsonResponse(response_data) + @csrf_exempt def bookListView(request): template_name = 'store/book_list.html' + data=request.GET + print(len(data)) + if(len(data)>0): + books=Book.objects.filter(title__icontains=data['title'],author__icontains=data['author'],genre__icontains=data['genre']) + else: + books=Book.objects.all() context = { - 'books': None, # set this to the list of required books upon filtering using the GET parameters + 'books': books, # 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) } get_data = request.GET @@ -38,14 +82,15 @@ def bookListView(request): @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 @@ -54,15 +99,26 @@ def viewLoanedBooks(request): @csrf_exempt @login_required def loanBookView(request): + book_id = request.POST.get("bid") + book1=Book.objects.get(pk=book_id) + book=BookCopy.objects.filter(status__exact=True,book__exact=book1) + if(book): + message="success" + book[0].status=False + book[0].borrower=request.user + book[0].borrow_date= datetime.date.today() + book[0].save() + else: + message="failure" response_data = { - 'message': None, + 'message': message, } ''' 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 + # get the book id from post data return JsonResponse(response_data) @@ -77,6 +133,27 @@ def loanBookView(request): @csrf_exempt @login_required def returnBookView(request): - pass + book_id = request.POST.get("bid") + book=BookCopy.objects.get(id=book_id) + if(book): + message="success" + book.status=True + book.borrower=None + book.borrow_date=None + book.save() + else: + message="failure" + response_data = { + 'message': message, + } + ''' + Check if an instance of the asked book is available. + If yes, then set the message to 'success', otherwise 'failure' + ''' + # START YOUR CODE HERE + # get the book id from post data + + + return JsonResponse(response_data)