/DjangoAuctionApp

Auction made in Python/Django

Primary LanguageCSS

DjangoAuctionApp

Technologies used in project

  1. Python3
  2. Django3
  3. DRF (Django Rest Framework) - getting actual info by using REST (in this project by AJAX on frontend)
  4. Django Channels - websocket connection for bid system and chat
  5. Celery - automatic listing's completion by task with countdown
  6. Docker - project deploying (dev and prod deploying versions)

Description

Listing Creation


The listing creation process is simple, there are three fields that must be filled:
Name, Category, Start Price. Image and Description are optional.

When listing is created, Celery task is starting with countdown for created listing, countdown depends on the number of hours that was selected in the last field on Creation page.

Celery task:
def create_task(listing_id):

Task starting with new listing creation:
def createListing(request):
new_listing = AuctionListing.objects.create(name = name, description = description,loaded_image=image_file,image = image, category = category, user = user, startBid = startBid, creationDate = current_date, endDate = end_date, active = active)
new_listing.save()
seconds_to_end = int(datetime.timedelta.total_seconds(new_listing.endDate - new_listing.creationDate))
task = create_task.apply_async(kwargs = {"listing_id": new_listing.id}, countdown = seconds_to_end)

Index Page (Main page with all listings that exist)


On this page just displayed all listings that currently exist with main info about them in boxes. There are opportunity to show only Active, yours or with special Category listings.

Detail Listing's page


All information about listing displayed on it's detail page:
Name, image, price, last bid, time to end (JS live timer) and Owner

Websocket connection automatically opens with anyone, who entered on this page. (separed connection groups for each listing). Websocket connection makes "live" bid system and comments.
class ListingConsumer(WebsocketConsumer):
class ListingConsumer(WebsocketConsumer):
    def connect(self):
        self.user = self.scope['user']
        self.room_name = self.scope['url_route']['kwargs']['listing_id']
        self.room_group_name = 'market_%s' % self.room_name

        #Join room group by listing url
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
            )
        self.accept()

Inbox and Chat


On inbox page you can enter to chat that exists between you and other user, or you can create new chat, but only if you haven't chat created with target user already.

Websocket connection for chat system is active on every page and only for Authorized user's.
Every Authorized user connects to websocket on Chat Consumer and have it's own "connection group" with himself only. It's safety, cause only target user will get websocket message on his client and there are still posible to show new messages count in 'live' with Inbox NavBar menu
class ChatConsumer(WebsocketConsumer):
class ChatConsumer(WebsocketConsumer):
    def connect(self):
        self.user = self.scope['user']
        if self.user.is_active == True and self.user.is_anonymous == False:
            self.room_group_name = f'chat_{self.user.id}'

            # Join room group
            async_to_sync(self.channel_layer.group_add)(
                self.room_group_name,
                self.channel_name
            )

            self.accept()
        else:
            self.close()

User Cabinet


It is simple user's cabinet, where possible to see main information about User.
There are also opportunity to change user's Avatar. Using template Django form and Pillow allow to save media files in safety way. (To make sure that is really media files)

Installation

Basic requirements

Install Docker Engine and Docker Compose on your PC.

Development

  1. Rename .env.dev-sample to .env.dev.

  2. Update the environment variables in the docker-compose.yml and .env.dev files.

  3. Build the images and run the containers:

    $ docker-compose up -d --build
  4. Don't forget to create superuser (needs to get access to admin panel)

    $ docker-compose exec web python3 manage.py createsuperuser

Test it out at http://localhost:8000(http://127.0.0.1:8000).

Production

Uses daphne + nginx.
  1. Rename .env.prod-sample to .env.prod and .env.prod.db-sample to .env.prod.db. Update the environment variables as you need.

  2. Build the images and run the containers:

    $ docker-compose -f docker-compose.prod.yml up -d --build
  3. Make migartions to DB

    $ docker-compose -f docker-compose.prod.yml exec web python3 manage.py makemigrations
    $ docker-compose -f docker-compose.prod.yml exec web python3 manage.py migrate
  4. Collect staticfiles

    $ docker-compose -f docker-compose.prod.yml exec web python3 manage.py collectstatic
  5. Don't forget to create superuser (needs to get access to admin panel)

    $ docker-compose exec web python3 manage.py createsuperuser

Autotests

It's nice practice to run tests before and after making some changes and before deploying. Major part of project's fucntions are covered by autotests, to run it execute command below:

Development

$ docker-compose exec web pytest

Production

$ docker-compose -f docker-compose.prod.yml exec web pytest

Test it out at http://localhost:1337(http://127.0.0.1:1337). To apply changes, the image must be re-built.