diff --git a/Django/Bidding app/auctions/__init__.py b/Django/Bidding app/auctions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Django/Bidding app/auctions/admin.py b/Django/Bidding app/auctions/admin.py new file mode 100644 index 0000000..86821a5 --- /dev/null +++ b/Django/Bidding app/auctions/admin.py @@ -0,0 +1,7 @@ +from django.contrib import admin +from .models import Listing, Bid, Comments +# Register your models here. + +admin.site.register(Listing) +admin.site.register(Bid) +admin.site.register(Comments) diff --git a/Django/Bidding app/auctions/apps.py b/Django/Bidding app/auctions/apps.py new file mode 100644 index 0000000..8ed8571 --- /dev/null +++ b/Django/Bidding app/auctions/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class AuctionsConfig(AppConfig): + name = 'auctions' diff --git a/Django/Bidding app/auctions/forms.py b/Django/Bidding app/auctions/forms.py new file mode 100644 index 0000000..10454cf --- /dev/null +++ b/Django/Bidding app/auctions/forms.py @@ -0,0 +1,7 @@ +from .models import Listing +from django.forms import ModelForm + +class ListingForm(ModelForm): + class Meta: + model = Listing + exclude = ['closed', 'date', 'user'] diff --git a/Django/Bidding app/auctions/migrations/__init__.py b/Django/Bidding app/auctions/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Django/Bidding app/auctions/models.py b/Django/Bidding app/auctions/models.py new file mode 100644 index 0000000..84a89db --- /dev/null +++ b/Django/Bidding app/auctions/models.py @@ -0,0 +1,43 @@ + +from django.contrib.auth.models import AbstractUser +from django.db import models +import datetime + +category_choice =( +('Electronics', 'Electronics'), +('Fashion','Fashion'), +('Homedecor', 'Homedecor'), +('Automobiles', 'Automobiles'), +('Sports equipment', 'Sports equipment'), +('Music equipment', 'Music equipment'), +('Books', 'Books'), +('Miscallenous', 'Miscallenous') +) + +class User(AbstractUser, ): + watchlist = models.ManyToManyField('Listing', related_name="w") + + +class Listing(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="owner") + title = models.CharField(max_length=20) + description = models.TextField() + startbid = models.IntegerField() + image_link = models.URLField( blank = True) + category = models.CharField(max_length=63, blank=True, null=True, choices=category_choice) + closed =models.BooleanField(default=False) + date = models.DateTimeField(default=datetime.datetime.now) + + def __str__(self): + return f"{self.id}:{self.title}{self.description}{self.startbid}{self.category}" + +class Bid(models.Model): + amount = models.IntegerField() + bidder = models.ForeignKey(User,on_delete=models.CASCADE, related_name="bider") + bid = models.ForeignKey(Listing, on_delete = models.CASCADE, related_name= "bidamt") + +class Comments(models.Model): + comment = models.TextField() + commenter = models.ForeignKey(User,on_delete=models.CASCADE, related_name="commenterr") + d = models.DateTimeField(default=datetime.datetime.now) + rlist = models.ForeignKey(Listing, on_delete = models.CASCADE, related_name="currentcomment") diff --git a/Django/Bidding app/auctions/static/auctions/styles.css b/Django/Bidding app/auctions/static/auctions/styles.css new file mode 100644 index 0000000..d61a8dd --- /dev/null +++ b/Django/Bidding app/auctions/static/auctions/styles.css @@ -0,0 +1,3 @@ +body { + padding: 10px; +} diff --git a/Django/Bidding app/auctions/templates/auctions/category.html b/Django/Bidding app/auctions/templates/auctions/category.html new file mode 100644 index 0000000..e68433d --- /dev/null +++ b/Django/Bidding app/auctions/templates/auctions/category.html @@ -0,0 +1,9 @@ +{% extends "auctions/layout.html" %} + +{% block body %} + +{% for i in clist %} + +{% endfor %} + +{% endblock %} diff --git a/Django/Bidding app/auctions/templates/auctions/index.html b/Django/Bidding app/auctions/templates/auctions/index.html new file mode 100644 index 0000000..6914ce7 --- /dev/null +++ b/Django/Bidding app/auctions/templates/auctions/index.html @@ -0,0 +1,34 @@ +{% extends "auctions/layout.html" %} + +{% block body %} +

Active Listings

+ + {% if present == 0 and user.is_authenticated %} +

No such listing

+ {% endif %} + + + + TODO +{% endblock %} diff --git a/Django/Bidding app/auctions/templates/auctions/layout.html b/Django/Bidding app/auctions/templates/auctions/layout.html new file mode 100644 index 0000000..0ee8cfe --- /dev/null +++ b/Django/Bidding app/auctions/templates/auctions/layout.html @@ -0,0 +1,69 @@ +{% load static %} + + + + + {% block title %}Auctions{% endblock %} + + + + + + +
+ +

Auctions

+
+ {% if user.is_authenticated %} + Signed in as {{ user.username }}. + {% else %} + Not signed in. + {% endif %} +
+
+ +
+ {% block body %} + {% endblock %} + + diff --git a/Django/Bidding app/auctions/templates/auctions/list.html b/Django/Bidding app/auctions/templates/auctions/list.html new file mode 100644 index 0000000..0fe201d --- /dev/null +++ b/Django/Bidding app/auctions/templates/auctions/list.html @@ -0,0 +1,17 @@ +{% extends "auctions/layout.html" %} +{% block body %} +
+ {% if error %} + + {% endif %} +
+ +
+ {% csrf_token %} + {{form.as_p}} + +
+ +{% endblock %} diff --git a/Django/Bidding app/auctions/templates/auctions/listing.html b/Django/Bidding app/auctions/templates/auctions/listing.html new file mode 100644 index 0000000..ada4407 --- /dev/null +++ b/Django/Bidding app/auctions/templates/auctions/listing.html @@ -0,0 +1,79 @@ +{% extends "auctions/layout.html" %} + +{% block body %} +

{{listing.title}}

+ {% if wlist %} + + {% else %} + + {% endif %} +
+ {{listing.title}} +
+ created on {{listing.date}} +



+
+ {{listing.description}} +
+ {% if not listing.closed %} +
+ {% if amount == listing.startbid %} + Current bid:NO BID + {% else %} + Current bid: {{amount}} + {% endif %} +
+ Startbid: {{listing.startbid}} + +
+
+
+ {% csrf_token %} + + +
+
+
+

+ {% if listing in own %} + + {% endif %} +

+
+ {% csrf_token %} + < + +
+
+



+

Comments

+

+ {% for c in comments %} + +
+
{{c.commenter.username}}
+ {{c.d}} +
+

{{c.comment}}

+
+ {% endfor %} + {% else %} + {% if r %} +

Congratulations! You have won this auction

+ {% endif %} + +
+
+ {% for c in comments %} + +
+
{{c.commmenter.username}}
+ {{c.d}} +
+

{{c.comment}}

+
+ {% endfor %} + {% endif %} +{% endblock %} diff --git a/Django/Bidding app/auctions/templates/auctions/login.html b/Django/Bidding app/auctions/templates/auctions/login.html new file mode 100644 index 0000000..67624a4 --- /dev/null +++ b/Django/Bidding app/auctions/templates/auctions/login.html @@ -0,0 +1,24 @@ +{% extends "auctions/layout.html" %} + +{% block body %} + +

Login

+ + {% if message %} +
{{ message }}
+ {% endif %} + +
+ {% csrf_token %} +
+ +
+
+ +
+ +
+ + Don't have an account? Register here. + +{% endblock %} \ No newline at end of file diff --git a/Django/Bidding app/auctions/templates/auctions/register.html b/Django/Bidding app/auctions/templates/auctions/register.html new file mode 100644 index 0000000..47e956f --- /dev/null +++ b/Django/Bidding app/auctions/templates/auctions/register.html @@ -0,0 +1,30 @@ +{% extends "auctions/layout.html" %} + +{% block body %} + +

Register

+ + {% if message %} +
{{ message }}
+ {% endif %} + +
+ {% csrf_token %} +
+ +
+
+ +
+
+ +
+
+ +
+ +
+ + Already have an account? Log In here. + +{% endblock %} \ No newline at end of file diff --git a/Django/Bidding app/auctions/templates/auctions/watchlist.html b/Django/Bidding app/auctions/templates/auctions/watchlist.html new file mode 100644 index 0000000..2e9d48f --- /dev/null +++ b/Django/Bidding app/auctions/templates/auctions/watchlist.html @@ -0,0 +1,34 @@ +{% extends "auctions/layout.html" %} + +{% block body %} +

Watchlist

+ + {% if present == 0 and user.is_authenticated %} +

Watchlist is empty 😫

+ {% endif %} + + + + TODO + {% endblock %} diff --git a/Django/Bidding app/auctions/tests.py b/Django/Bidding app/auctions/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/Django/Bidding app/auctions/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/Django/Bidding app/auctions/urls.py b/Django/Bidding app/auctions/urls.py new file mode 100644 index 0000000..f2bfd88 --- /dev/null +++ b/Django/Bidding app/auctions/urls.py @@ -0,0 +1,18 @@ +from django.urls import path + +from . import views + +urlpatterns = [ + path("", views.index, name="index"), + path("login", views.login_view, name="login"), + path("logout", views.logout_view, name="logout"), + path("register", views.register, name="register"), + path("createlist", views.createlist, name="createlist"), + path("listview/", views.listview, name="listview"), + path("watchlist//", views.watchlist, name="watchlist"), + path("show_watchlist", views.show_watchlist, name="show_watchlist"), + path("bid/", views.bid, name="bid"), + path("comment/", views.comment, name="comment"), + path("close/", views.close, name="close"), + path("category/", views.category, name="category") +] diff --git a/Django/Bidding app/auctions/views.py b/Django/Bidding app/auctions/views.py new file mode 100644 index 0000000..0494a4a --- /dev/null +++ b/Django/Bidding app/auctions/views.py @@ -0,0 +1,182 @@ +from django.contrib.auth import authenticate, login, logout +from django.db import IntegrityError +from django.http import HttpResponse, HttpResponseRedirect +from django.shortcuts import render +from django.urls import reverse +from django.forms import ModelForm +from .models import User, Listing, Bid, Comments +from .forms import ListingForm + + +def index(request): + if( User.objects.filter(username=request.user.username).exists()): + list = Listing.objects.all() + amt=[] + for item in list: + if(Bid.objects.filter(bid=item).exists()): + currentbid = Bid.objects.get(bid=item) + amt.append(currentbid.amount) + else: + amt.append(item.startbid) + List= zip(list,amt) + return render(request, "auctions/index.html", {'List':List}) + else: + return render(request, "auctions/index.html", {'present':0, 'amt':" "}) + + +def login_view(request): + if request.method == "POST": + + # Attempt to sign user in + username = request.POST["username"] + password = request.POST["password"] + user = authenticate(request, username=username, password=password) + + # Check if authentication successful + if user is not None: + login(request, user) + return HttpResponseRedirect(reverse("index")) + else: + return render(request, "auctions/login.html", { + "message": "Invalid username and/or password." + }) + else: + return render(request, "auctions/login.html") + + +def logout_view(request): + logout(request) + return HttpResponseRedirect(reverse("index")) + + +def register(request): + if request.method == "POST": + username = request.POST["username"] + email = request.POST["email"] + + # Ensure password matches confirmation + password = request.POST["password"] + confirmation = request.POST["confirmation"] + if password != confirmation: + return render(request, "auctions/register.html", { + "message": "Passwords must match." + }) + + # Attempt to create new user + try: + user = User.objects.create_user(username, email, password) + user.save() + except IntegrityError: + return render(request, "auctions/register.html", { + "message": "Username already taken." + }) + login(request, user) + return HttpResponseRedirect(reverse("index")) + else: + return render(request, "auctions/register.html") + + +def createlist(request): + if request.method == "GET": + form = ListingForm() + return render(request, "auctions/list.html", {'form':form, 'error':False}) + else: + l = Listing(user=User.objects.get(username=request.user.username)) + form = ListingForm(request.POST, instance=l) + if form.is_valid(): + form.save() + else: + form = ListingForm() + return render(request, "auctions/list.html", {'form':form, 'error':True}) + return index(request) + +def listview(request,item): + it = Listing.objects.get(id=item) + u = User.objects.get(username=request.user.username) + wl = User.objects.get(username=request.user.username).watchlist.all() + if(Bid.objects.filter(bid=it).exists()): + currentbid = Bid.objects.get(bid=it) + amt = currentbid.amount + if(u.id == currentbid.bidder.id): + result = True + else: + result = False + else: + amt = it.startbid + result = False + cmt = Comments.objects.filter(rlist=it) + + own = u.owner.all() + + + if it in wl: + return render(request, 'auctions/listing.html' ,{'listing':it, 'wlist':True, 'amount':amt, 'comments':cmt, 'own':own, 'r':result}) + else: + return render(request, 'auctions/listing.html' ,{'listing':it, 'wlist':False, 'amount':amt, 'comments':cmt, 'own':own, 'r':result}) + +def watchlist(request,list,remove): + if remove==0: + user = User.objects.get(username=request.user.username) + user.watchlist.add(Listing.objects.get(id=list)) + else: + user = User.objects.get(username=request.user.username) + user.watchlist.remove(Listing.objects.get(id=list)) + return show_watchlist(request) + +def show_watchlist(request): + user = User.objects.get(username=request.user.username) + list = user.watchlist.all() + amt=[] + for item in list: + if(Bid.objects.filter(bid=item).exists()): + currentbid = Bid.objects.get(bid=item) + amt.append(currentbid.amount) + else: + amt = item.startbid + if(len(list) == 0): + return render(request, "auctions/watchlist.html", {'present':0, 'amt':" "}) + else: + List= zip(list,amt) + return render(request, "auctions/watchlist.html", {'List':List}) +def bid(request, i): + userr = User.objects.get(username=request.user.username) + if (Bid.objects.filter(bid=Listing.objects.get(id=i)).exists()): + currentbid = Bid.objects.get(bid=Listing.objects.get(id=i)) + currentbid.amount = request.POST['quantity'] + currentbid.bidder = userr + currentbid.save() + return listview(request, i) + + else: + b = Bid(bid=Listing.objects.get(id=i),bidder=userr,amount=request.POST['quantity']) + b.save() + return listview(request, i) + +def comment(request,li): + c = Comments(rlist=Listing.objects.get(id=li), commenter=User.objects.get(username=request.user.username), comment=request.POST['name']) + c.save() + return listview(request,li) + +def close(request,list): + c = Listing.objects.get(id=list) + c.closed = True + c.save() + return listview(request,list) + +def category(request,cat): + if cat == " ": + return render(request, "auctions/category.html", {'clist':['Electronics','Fashion','Homedecor','Automobiles','Sports equipment','Music equipment','Books','Miscallenous']}) + else: + if(Listing.objects.filter(category=cat).exists()): + l = Listing.objects.filter(category=cat) + amt=[] + for item in l: + if(Bid.objects.filter(bid=item).exists()): + currentbid = Bid.objects.get(bid=item) + amt.append(currentbid.amount) + else: + amt.append(item.startbid) + List= zip(l,amt) + return render(request, "auctions/index.html", {'List':List}) + else: + return render(request, "auctions/index.html", {'present':0, 'amt':" "}) diff --git a/Django/Bidding app/commerce/__init__.py b/Django/Bidding app/commerce/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Django/Bidding app/commerce/asgi.py b/Django/Bidding app/commerce/asgi.py new file mode 100644 index 0000000..5594f23 --- /dev/null +++ b/Django/Bidding app/commerce/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for commerce project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'commerce.settings') + +application = get_asgi_application() diff --git a/Django/Bidding app/commerce/settings.py b/Django/Bidding app/commerce/settings.py new file mode 100644 index 0000000..84b3444 --- /dev/null +++ b/Django/Bidding app/commerce/settings.py @@ -0,0 +1,122 @@ +""" +Django settings for commerce project. + +Generated by 'django-admin startproject' using Django 3.0.2. + +For more information on this file, see +https://docs.djangoproject.com/en/3.0/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/3.0/ref/settings/ +""" + +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '#' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'auctions', + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', +] + +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', +] + +ROOT_URLCONF = 'commerce.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'commerce.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/3.0/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + +AUTH_USER_MODEL = 'auctions.User' + +# Password validation +# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/3.0/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/3.0/howto/static-files/ + +STATIC_URL = '/static/' diff --git a/Django/Bidding app/commerce/urls.py b/Django/Bidding app/commerce/urls.py new file mode 100644 index 0000000..2f7a9e0 --- /dev/null +++ b/Django/Bidding app/commerce/urls.py @@ -0,0 +1,22 @@ +"""commerce URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/3.0/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import include, path + +urlpatterns = [ + path("admin/", admin.site.urls), + path("", include("auctions.urls")) +] \ No newline at end of file diff --git a/Django/Bidding app/commerce/wsgi.py b/Django/Bidding app/commerce/wsgi.py new file mode 100644 index 0000000..054e015 --- /dev/null +++ b/Django/Bidding app/commerce/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for commerce project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'commerce.settings') + +application = get_wsgi_application() diff --git a/Django/Bidding app/db.sqlite3 b/Django/Bidding app/db.sqlite3 new file mode 100644 index 0000000..6260ec5 Binary files /dev/null and b/Django/Bidding app/db.sqlite3 differ diff --git a/Django/Bidding app/manage.py b/Django/Bidding app/manage.py new file mode 100644 index 0000000..bea064a --- /dev/null +++ b/Django/Bidding app/manage.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'commerce.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main()