diff --git a/auctions/__init__.py b/auctions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/auctions/__pycache__/__init__.cpython-37.pyc b/auctions/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..7342046 Binary files /dev/null and b/auctions/__pycache__/__init__.cpython-37.pyc differ diff --git a/auctions/__pycache__/admin.cpython-37.pyc b/auctions/__pycache__/admin.cpython-37.pyc new file mode 100644 index 0000000..bdfb581 Binary files /dev/null and b/auctions/__pycache__/admin.cpython-37.pyc differ diff --git a/auctions/__pycache__/models.cpython-37.pyc b/auctions/__pycache__/models.cpython-37.pyc new file mode 100644 index 0000000..d3d8c8d Binary files /dev/null and b/auctions/__pycache__/models.cpython-37.pyc differ diff --git a/auctions/__pycache__/urls.cpython-37.pyc b/auctions/__pycache__/urls.cpython-37.pyc new file mode 100644 index 0000000..4eb3204 Binary files /dev/null and b/auctions/__pycache__/urls.cpython-37.pyc differ diff --git a/auctions/__pycache__/views.cpython-37.pyc b/auctions/__pycache__/views.cpython-37.pyc new file mode 100644 index 0000000..13fd5fd Binary files /dev/null and b/auctions/__pycache__/views.cpython-37.pyc differ diff --git a/auctions/admin.py b/auctions/admin.py new file mode 100644 index 0000000..796f3d3 --- /dev/null +++ b/auctions/admin.py @@ -0,0 +1,9 @@ +from django.contrib import admin +from .models import User +from .models import AuctionListing,Comment,Bids + +# Register your models here. +admin.site.register(User) +admin.site.register(AuctionListing) +admin.site.register(Comment) +admin.site.register(Bids) diff --git a/auctions/apps.py b/auctions/apps.py new file mode 100644 index 0000000..8ed8571 --- /dev/null +++ b/auctions/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class AuctionsConfig(AppConfig): + name = 'auctions' diff --git a/auctions/migrations/0001_initial.py b/auctions/migrations/0001_initial.py new file mode 100644 index 0000000..e063ad8 --- /dev/null +++ b/auctions/migrations/0001_initial.py @@ -0,0 +1,82 @@ +# Generated by Django 3.0.8 on 2020-10-19 17:27 + +from django.conf import settings +import django.contrib.auth.models +import django.contrib.auth.validators +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0011_update_proxy_permissions'), + ] + + operations = [ + migrations.CreateModel( + name='User', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), + ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), + ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), + ], + options={ + 'verbose_name': 'user', + 'verbose_name_plural': 'users', + 'abstract': False, + }, + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + migrations.CreateModel( + name='AuctionListing', + fields=[ + ('title', models.CharField(max_length=64, primary_key=True, serialize=False)), + ('price', models.DecimalField(decimal_places=2, max_digits=10)), + ('desc', models.CharField(max_length=1000)), + ('picture', models.URLField(default='https://www.riobeauty.co.uk/images/product_image_not_found.gif')), + ('category', models.CharField(choices=[('Fashion', 'Fashion'), ('Electronics', 'Electronics'), ('Home', 'Home'), ('Sports', 'Sports'), ('Toys', 'Toys'), ('Automobile', 'Automobile'), ('Books', 'Books'), ('Videogames', 'Videogames'), ('Other', 'Other')], max_length=64)), + ('date_added', models.DateTimeField(auto_now_add=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Comment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('body', models.TextField()), + ('date_added', models.DateTimeField(auto_now_add=True)), + ('listing', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='auctions.AuctionListing')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='commited_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Bids', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('bid_value', models.DecimalField(decimal_places=2, max_digits=10)), + ('listing', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='bidding_listing', to='auctions.AuctionListing')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='bidding_user', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.AddField( + model_name='user', + name='watchlist', + field=models.ManyToManyField(blank=True, related_name='watchlists', to='auctions.AuctionListing'), + ), + ] diff --git a/auctions/migrations/0002_auctionlisting_closed.py b/auctions/migrations/0002_auctionlisting_closed.py new file mode 100644 index 0000000..4d544ab --- /dev/null +++ b/auctions/migrations/0002_auctionlisting_closed.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.8 on 2020-10-21 11:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('auctions', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='auctionlisting', + name='closed', + field=models.BooleanField(default=False), + ), + ] diff --git a/auctions/migrations/__init__.py b/auctions/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/auctions/migrations/__pycache__/0001_initial.cpython-37.pyc b/auctions/migrations/__pycache__/0001_initial.cpython-37.pyc new file mode 100644 index 0000000..1fe3eb0 Binary files /dev/null and b/auctions/migrations/__pycache__/0001_initial.cpython-37.pyc differ diff --git a/auctions/migrations/__pycache__/0002_auctionlisting_closed.cpython-37.pyc b/auctions/migrations/__pycache__/0002_auctionlisting_closed.cpython-37.pyc new file mode 100644 index 0000000..a78b398 Binary files /dev/null and b/auctions/migrations/__pycache__/0002_auctionlisting_closed.cpython-37.pyc differ diff --git a/auctions/migrations/__pycache__/0002_remove_auctionlisting_date_added.cpython-37.pyc b/auctions/migrations/__pycache__/0002_remove_auctionlisting_date_added.cpython-37.pyc new file mode 100644 index 0000000..d727c80 Binary files /dev/null and b/auctions/migrations/__pycache__/0002_remove_auctionlisting_date_added.cpython-37.pyc differ diff --git a/auctions/migrations/__pycache__/0003_auctionlisting_date_added.cpython-37.pyc b/auctions/migrations/__pycache__/0003_auctionlisting_date_added.cpython-37.pyc new file mode 100644 index 0000000..fd96d76 Binary files /dev/null and b/auctions/migrations/__pycache__/0003_auctionlisting_date_added.cpython-37.pyc differ diff --git a/auctions/migrations/__pycache__/0004_comment.cpython-37.pyc b/auctions/migrations/__pycache__/0004_comment.cpython-37.pyc new file mode 100644 index 0000000..1e76d7f Binary files /dev/null and b/auctions/migrations/__pycache__/0004_comment.cpython-37.pyc differ diff --git a/auctions/migrations/__pycache__/0005_auto_20201018_2304.cpython-37.pyc b/auctions/migrations/__pycache__/0005_auto_20201018_2304.cpython-37.pyc new file mode 100644 index 0000000..3d2de5c Binary files /dev/null and b/auctions/migrations/__pycache__/0005_auto_20201018_2304.cpython-37.pyc differ diff --git a/auctions/migrations/__pycache__/0006_auto_20201019_1109.cpython-37.pyc b/auctions/migrations/__pycache__/0006_auto_20201019_1109.cpython-37.pyc new file mode 100644 index 0000000..034785c Binary files /dev/null and b/auctions/migrations/__pycache__/0006_auto_20201019_1109.cpython-37.pyc differ diff --git a/auctions/migrations/__pycache__/0007_auto_20201019_1723.cpython-37.pyc b/auctions/migrations/__pycache__/0007_auto_20201019_1723.cpython-37.pyc new file mode 100644 index 0000000..9b71298 Binary files /dev/null and b/auctions/migrations/__pycache__/0007_auto_20201019_1723.cpython-37.pyc differ diff --git a/auctions/migrations/__pycache__/0008_auto_20201019_1725.cpython-37.pyc b/auctions/migrations/__pycache__/0008_auto_20201019_1725.cpython-37.pyc new file mode 100644 index 0000000..e2bb230 Binary files /dev/null and b/auctions/migrations/__pycache__/0008_auto_20201019_1725.cpython-37.pyc differ diff --git a/auctions/migrations/__pycache__/0009_auto_20201019_1740.cpython-37.pyc b/auctions/migrations/__pycache__/0009_auto_20201019_1740.cpython-37.pyc new file mode 100644 index 0000000..838d4ce Binary files /dev/null and b/auctions/migrations/__pycache__/0009_auto_20201019_1740.cpython-37.pyc differ diff --git a/auctions/migrations/__pycache__/0010_auto_20201019_1744.cpython-37.pyc b/auctions/migrations/__pycache__/0010_auto_20201019_1744.cpython-37.pyc new file mode 100644 index 0000000..13a0c25 Binary files /dev/null and b/auctions/migrations/__pycache__/0010_auto_20201019_1744.cpython-37.pyc differ diff --git a/auctions/migrations/__pycache__/__init__.cpython-37.pyc b/auctions/migrations/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..72625fe Binary files /dev/null and b/auctions/migrations/__pycache__/__init__.cpython-37.pyc differ diff --git a/auctions/models.py b/auctions/models.py new file mode 100644 index 0000000..9c4019d --- /dev/null +++ b/auctions/models.py @@ -0,0 +1,46 @@ +from django.contrib.auth.models import AbstractUser +from django.db import models + +class User(AbstractUser): + watchlist = models.ManyToManyField('AuctionListing',blank = True,related_name="watchlists") + +class AuctionListing(models.Model): + category_choices = ( + ('Fashion','Fashion'), + ('Electronics','Electronics'), + ('Home','Home'), + ('Sports','Sports'), + ('Toys','Toys'), + ('Automobile','Automobile'), + ('Books','Books'), + ('Videogames','Videogames'), + ('Other','Other'), + ) + title = models.CharField(max_length = 64,primary_key = True) + user = models.ForeignKey(User,on_delete = models.CASCADE) + price = models.DecimalField(max_digits = 10,decimal_places = 2) + desc = models.CharField(max_length = 1000) + picture = models.URLField(default="https://www.riobeauty.co.uk/images/product_image_not_found.gif") + category = models.CharField(max_length = 64,choices=category_choices) + date_added = models.DateTimeField(auto_now_add=True) + closed = models.BooleanField(default=False) + + def __str__(self): + return f"{self.title}: {self.price},{self.desc},{self.picture},{self.category},{self.date_added}" + + +class Comment(models.Model): + listing = models.ForeignKey(AuctionListing,on_delete = models.CASCADE,related_name="comments") + user = models.ForeignKey(User,related_name="commited_user",on_delete=models.CASCADE) + body = models.TextField() + date_added = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return '%s - %s' % (self.listing.title, self.user) +class Bids(models.Model): + bid_value = models.DecimalField(max_digits = 10,decimal_places = 2) + user = models.ForeignKey(User,on_delete = models.CASCADE, related_name="bidding_user") + listing = models.ForeignKey(AuctionListing, on_delete= models.CASCADE, related_name="bidding_listing") + + def __str__(self): + return '%s - %s - %s' % (self.bid_value, self.user, self.listing) diff --git a/auctions/static/auctions/styles.css b/auctions/static/auctions/styles.css new file mode 100644 index 0000000..d61a8dd --- /dev/null +++ b/auctions/static/auctions/styles.css @@ -0,0 +1,3 @@ +body { + padding: 10px; +} diff --git a/auctions/templates/auctions/all_listings.html b/auctions/templates/auctions/all_listings.html new file mode 100644 index 0000000..ba65f56 --- /dev/null +++ b/auctions/templates/auctions/all_listings.html @@ -0,0 +1,89 @@ +{% extends "auctions/layout.html" %} + +{% block body %} +

All Listings

+ {% if Listings %} +
+ {% for listing in Listings %} +
+ +
+
+ Preview not found + +
+
+

{{ listing.title }}


+ + {% if not listing.closed %} +

+ {% for bidding in listing.bidding_listing.all %} + bid price : ${{bidding.bid_value}}
+ Last bid by: {{ bidding.user }} +
+ Description: {{ listing.desc }}
+ {% endfor %} + + created on {{listing.date_added}} +

+ {% else %} +

+ CLOSED +
+ This listing is over. +
+
+ {% for bidding in listing.bidding_listing.all %} + {% if user == bidding.user %} + You won this listing!!! + {% else %} + This is won by @{{ bidding.user }} + for ${{bidding.bid_value}} + {% endif %} + {% endfor %} + +

+ {% endif %} + + +
+ {% if listing.closed %} + + + {% elif user.is_authenticated %} + +
+ {% csrf_token %} + {% if user not in listing.watchlists.all %} + + {% else %} + + {% endif %} + + +
+ {% else %} + log in to watch this listing + + {% endif %} + + +
+ +
+
+
+
+
+ {% endfor %} +
+ {% else %} +
+
+
+
+

Seems to be no listings in this Auction!!

+
+ {% endif %} + +{% endblock %} \ No newline at end of file diff --git a/auctions/templates/auctions/category.html b/auctions/templates/auctions/category.html new file mode 100644 index 0000000..c8e873f --- /dev/null +++ b/auctions/templates/auctions/category.html @@ -0,0 +1,88 @@ +{% extends "auctions/layout.html"%} + +{% block body %} +

Listings under category "{{ cat_name }}"

+ {% if listings %} +
+ + {% for list in listings %} +
+ +
+
+ Preview not found + +
+
+

{{ list.title }}


+ {% if not list.closed %} +

+ {% for bidding in list.bidding_listing.all %} + bid price : ${{bidding.bid_value}}
+ Last bid by: {{bidding.user}} +
+ created by: {{list.user}}
+ {% endfor %} + + created on {{list.date_added}} +

+ {% else %} +

+ CLOSED +
+ This listing is over. +
+
+ {% for bidding in list.bidding_listing.all %} + {% if user == bidding.user %} + You won this listing!!! + {% else %} + This is won by @{{ bidding.user }} + for ${{bidding.bid_value}} + {% endif %} + {% endfor %} + +

+ {% endif %} +
+ {% if list.closed %} + + + {% elif user.is_authenticated %} + +
+ {% csrf_token %} + {% if user not in list.watchlists.all %} + + {% else %} + + {% endif %} + + +
+ {% else %} + log in to watch this listing + + {% endif %} + + +
+ +
+
+
+
+
+ + {% endfor %} +
+ + {% else %} +
+
+
+
+

Seems to be no listings in this category

+
+ {% endif %} +{% endblock %} \ No newline at end of file diff --git a/auctions/templates/auctions/category_listing.html b/auctions/templates/auctions/category_listing.html new file mode 100644 index 0000000..7d9f73e --- /dev/null +++ b/auctions/templates/auctions/category_listing.html @@ -0,0 +1,19 @@ +{% extends "auctions/layout.html" %} + +{% block body %} +
+
+

Categories

+

Select category to browse through listings

+
+
+
+ + Select any one of the following + + {% for cat in categories %} + {{cat}} + {% endfor %} +
+ +{% endblock %} diff --git a/auctions/templates/auctions/create_listing.html b/auctions/templates/auctions/create_listing.html new file mode 100644 index 0000000..9001e5a --- /dev/null +++ b/auctions/templates/auctions/create_listing.html @@ -0,0 +1,34 @@ +{% extends "auctions/layout.html" %} + +{% block body %} + +

Create Listing

+ + +
+ {% csrf_token %} +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ + +{% endblock %} \ No newline at end of file diff --git a/auctions/templates/auctions/index.html b/auctions/templates/auctions/index.html new file mode 100644 index 0000000..5ec72b1 --- /dev/null +++ b/auctions/templates/auctions/index.html @@ -0,0 +1,72 @@ +{% extends "auctions/layout.html" %} + +{% block body %} +

Active Listings

+ {% if Listings %} +
+ {% for listing in Listings %} + {% if not listing.closed %} +
+ +
+
+ Preview not found + +
+
+

{{ listing.title }}


+ +

+ {% for bidding in listing.bidding_listing.all %} + bid price : ${{bidding.bid_value}}
+ Last bid by: {{ bidding.user }} +
+ Description: {{ listing.desc }}
+ {% endfor %} + + created on {{listing.date_added}} +

+ + + + +
+ + {% if user.is_authenticated %} + +
+ {% csrf_token %} + {% if user not in listing.watchlists.all %} + + {% else %} + + {% endif %} + + +
+ {% else %} + log in to watch this listing + + {% endif %} + + +
+ +
+
+
+
+
+ {% endif %} + {% endfor %} +
+ {% else %} +
+
+
+
+

Seems to be no listings in this Auction!!

+
+ {% endif %} + +{% endblock %} \ No newline at end of file diff --git a/auctions/templates/auctions/layout.html b/auctions/templates/auctions/layout.html new file mode 100644 index 0000000..b249f50 --- /dev/null +++ b/auctions/templates/auctions/layout.html @@ -0,0 +1,62 @@ +{% 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/auctions/templates/auctions/listing.html b/auctions/templates/auctions/listing.html new file mode 100644 index 0000000..b9953ea --- /dev/null +++ b/auctions/templates/auctions/listing.html @@ -0,0 +1,97 @@ + +{% extends "auctions/layout.html" %} + +{% block body %} +

Listing : {{ Listing.title}}

+ +
+ {% if user.username|stringformat:"s" == Listing.user|stringformat:"s" and not Listing.closed %} + + Close this Listing + {% endif %} +
+ {% csrf_token %} + {% if user not in Listing.watchlists.all %} + + {% else %} + + {% endif %} + +
+
+ + +
+ +

{{Listing.desc}}

+ + {% if Listing.closed %} +
+

This listing is CLOSED

+
+

This Listing is won by @{{bids.user}} for ${{bids.bid_value}}

+ {% else %} +

${{bids.bid_value}} by @{{bids.user}}

+ +
+ {% if user.is_authenticated and user != Listing.user %} +
+ {% csrf_token %} + {{ bid_form }} + +
+ +
+ {% elif user.is_authenticated and user == Listing.user%} +
You can't bid on your own Listing
+ {% else %} +
+ Log In to bid on this Listing + {% endif %} + {% endif %} +
+
+

Comments ...

+ + {% if not Listing.comments.all %} + No comments Yet.... +
+
+
+ + {% else %} + {% for comment in Listing.comments.all %} + {{comment.user}} - {{comment.date_added}} +
+ {{ comment.body }} +
+
+ {% endfor %} + + + {% endif %} + {% if not Listing.closed%} +
Add comment
+

+

+ {% csrf_token %} + +
+ +
+

+ {% elif not user.is_authenticated %} +
+
+ Log In to comment on this listing + + {% else %} +
+
+ The Listing is CLOSED for comments + {% endif %} + + + + +{% endblock %} \ No newline at end of file diff --git a/auctions/templates/auctions/login.html b/auctions/templates/auctions/login.html new file mode 100644 index 0000000..67624a4 --- /dev/null +++ b/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/auctions/templates/auctions/register.html b/auctions/templates/auctions/register.html new file mode 100644 index 0000000..47e956f --- /dev/null +++ b/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/auctions/templates/auctions/watchlist.html b/auctions/templates/auctions/watchlist.html new file mode 100644 index 0000000..18b77b2 --- /dev/null +++ b/auctions/templates/auctions/watchlist.html @@ -0,0 +1,85 @@ +{% extends "auctions/layout.html" %} + +{% block body %} +

WatchList

+ {% if Watchlistings %} +
+ {% for listing in Watchlistings %} +
+ +
+
+ Preview not found + +
+
+

{{ listing.title }}


+ + {% if not listing.closed %} +

+ {% for bidding in listing.bidding_listing.all %} + bid price : ${{bidding.bid_value}}
+ Last bid by: {{bidding.user}} +
+ created by: {{listing.user}}
+ {% endfor %} + + created on {{listing.date_added}} +

+ {% else %} +

+ CLOSED +
+ This listing is over. +
+
+ {% for bidding in listing.bidding_listing.all %} + {% if user == bidding.user %} + You won this listing!!! + {% else %} + This is won by @{{ bidding.user }} + for ${{bidding.bid_value}} + {% endif %} + {% endfor %} + +

+ {% endif %} + + +
+ {% if listing.closed %} + + + {% elif user.is_authenticated %} + +
+ {% csrf_token %} + {% if user not in listing.watchlists.all %} + + {% else %} + + {% endif %} + + +
+ {% else %} + log in to watch this listing + + {% endif %} + + +
+ +
+
+
+
+
+ {% endfor %} +
+ {% else %} +

There seems to be no listing you are watching !! +

+ {% endif %} + +{% endblock %} \ No newline at end of file diff --git a/auctions/tests.py b/auctions/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/auctions/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/auctions/urls.py b/auctions/urls.py new file mode 100644 index 0000000..1df1157 --- /dev/null +++ b/auctions/urls.py @@ -0,0 +1,20 @@ +from django.urls import path + +from . import views + +urlpatterns = [ + path("", views.index, name="index"), + path("all",views.all_listings,name="all_listings"), + path("login", views.login_view, name="login"), + path("logout", views.logout_view, name="logout"), + path("register", views.register, name="register"), + path("watchlist", views.watchlist, name="watchlist"), + path("create", views.create, name="create"), + path("categories", views.category, name="categories"), + path("category/",views.category,name="individual_categories"), + path("listing/",views.listing,name="listing"), + path("category/listing/",views.listing,name="listing"), + path("watch/",views.watch,name="watch"), + path("bid/",views.bid,name="bid"), + path("close/",views.close_bid,name="close_bid"), +] diff --git a/auctions/views.py b/auctions/views.py new file mode 100644 index 0000000..817f0ac --- /dev/null +++ b/auctions/views.py @@ -0,0 +1,227 @@ +from django.contrib.auth import authenticate, login, logout +from django.db import IntegrityError +from django.http import HttpResponseRedirect +from django.shortcuts import render +from django.urls import reverse +from django import forms +from .models import User,AuctionListing,Comment,Bids + + +categories = ['Fashion','Electronics','Home','Sports','Toys','Automobile','Books','Videogames', 'Other'] + +class BidForm(forms.Form): + bid_value = 0.00 + + def __init__(self, bid_value,*args,**kwargs ): + super().__init__(*args,**kwargs) + self.bid_value = bid_value + 1 + self.fields['bid'].widget.attrs['min'] = self.bid_value + + bid = forms.DecimalField(decimal_places=2) + +def watch(request,title): + """ + Used to assign watchlist and unwatch for a user + + """ + if request.method =="POST": + listing_obj = AuctionListing.objects.get(title=title) + if request.user in listing_obj.watchlists.all(): + request.user.watchlist.remove(listing_obj) + else: + request.user.watchlist.add(listing_obj) + previous_url = request.POST.get('previous','/') + + return HttpResponseRedirect(previous_url) + +def watchlist(request): + """ + Used to display the page Watchlist + + """ + listings = request.user.watchlist.all() + + return render(request,"auctions/watchlist.html",{ + "Watchlistings": listings + }) + +def index(request): + """ + Used to Display the homepage + """ + listings = AuctionListing.objects.all() + + return render(request, "auctions/index.html",{ + "Listings":listings, + + }) +def all_listings(request): + """ + Used to display all the listings + """ + listings = AuctionListing.objects.all() + + return render(request,"auctions/all_listings.html",{ + "Listings":listings + }) + +def listing(request,title): + """ + Used to display the listing page and commenting + + """ + listing_obj = AuctionListing.objects.get(pk = title) + bids = Bids.objects.get(listing = listing_obj) + if request.method == "POST": + body = request.POST["comment_body"] + comment = Comment(user=request.user,listing=listing_obj,body = body) + comment.save() + + return render(request,"auctions/listing.html",{ + "Listing": listing_obj, + "bids" : bids, + "bid_form":BidForm(bids.bid_value) + }) + +def category(request,cat_name = None): + """ + Used to dispaly the category page + """ + if( cat_name != None): + if cat_name.capitalize() in categories: + + listings = AuctionListing.objects.filter(category=cat_name.capitalize()) + print(listings) + + return render(request, "auctions/category.html",{ + "listings":listings, + "cat_name": cat_name + + }) + + else: + return render(request,"auctions/category_listing.html",{ + "categories": categories + }) + +def login_view(request): + """ + Used to authenticate a user + + """ + 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): + """ + Used to log out a user + """ + logout(request) + return HttpResponseRedirect(reverse("index")) + + +def register(request): + """ + Used to register a user + """ + + 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 create(request): + """ + Used to create a Listing + """ + if request.method == "POST": + title = request.POST["title"] + desc = request.POST["desc"] + starting_bid = request.POST["starting_bid"] + photo_url = request.POST["photo"] + + # alternate photo to display + if photo_url == "": + photo_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/1/15/No_image_available_600_x_450.svg/1280px-No_image_available_600_x_450.svg.png" + category_value = request.POST["category"] + listing_obj = AuctionListing(title = title, desc = desc, user = request.user,price = starting_bid, picture = photo_url,category=category_value) + listing_obj.save() + bid_obj = Bids(bid_value = starting_bid, listing = listing_obj, user = request.user) + bid_obj.save() + return render(request,"auctions/index.html",{ + "Listings" : AuctionListing.objects.all() + }) + else: + return render(request,"auctions/create_listing.html",{ + "categories":categories + }) +def bid(request, title): + """ + Used to bid on a listing + """ + listing_value = AuctionListing.objects.get(title=title) + bid_obj = Bids.objects.get(listing = listing_value) + form = BidForm(bid_obj.bid_value,request.POST) + if form.is_valid(): + new_bid_value = form.cleaned_data["bid"] + bid_obj.bid_value = float("{0:.2f}".format(new_bid_value)) + bid_obj.user = request.user + bid_obj.save() + + return render(request,"auctions/listing.html",{ + "Listing": listing_value, + "bids" : bid_obj, + "bid_form":BidForm(bid_obj.bid_value) + }) +def close_bid(request,title): + """ + Used to end the listing and declare a winner + """ + listing_value = AuctionListing.objects.get(title=title) + listing_value.closed = True + listing_value.save() + + # get a hidden input to return back to same page + + previous_url = request.POST.get('previous','/') + return HttpResponseRedirect(previous_url) + + + + diff --git a/db.sqlite3 b/db.sqlite3 new file mode 100644 index 0000000..85f9d99 Binary files /dev/null and b/db.sqlite3 differ diff --git a/google b/google new file mode 100644 index 0000000..492f44c Binary files /dev/null and b/google differ diff --git a/google_9q82OQA b/google_9q82OQA new file mode 100644 index 0000000..492f44c Binary files /dev/null and b/google_9q82OQA differ diff --git a/image_google b/image_google new file mode 100644 index 0000000..492f44c Binary files /dev/null and b/image_google differ diff --git a/image_google_sTknGkm b/image_google_sTknGkm new file mode 100644 index 0000000..492f44c Binary files /dev/null and b/image_google_sTknGkm differ diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..bea064a --- /dev/null +++ b/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()