Skip to content

Social e-commerce site allowing users to "purchase" appointments or DIY items from friends for quarantine activities to do together

Notifications You must be signed in to change notification settings

bentsai10/Quaranthings

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Quaranthings

Social e-commerce site allowing users to "purchase" appointments or DIY items from friends for quarantine activities to do together

Quaranthings' purpose:
Connect users through activity appointments scheduled with intentionality and DIY items during isolated periods of quarantining

Accessing Quaranthings

  • Download this project from Github
  • Make sure you have python3 installed
  • Create a virtual environment and pip install django==2.2
  • Navigate to project level folder in terminal and run "python manage.py runserver"
  • Go to http://localhost:8000/ in your desired browser!
  • Enjoy Quaranthings!
  • (Deployment coming soon...)

How Quaranthings Works

  1. Login/Register to join the Quarangiver community to post Quaranthings, leave reviews, or add Quaranthings to your cart

  2. Both the login/register pages are equipped with validations to ensure data congruency

  3. Once logged in, you have access to your profile, your orders, and your own cart!

  4. Navigate to the Top Picks page to see the most popular items other Quarangivers have posted

  5. The top picks page is equipped with AJAX filtering fictions, allowing you to narrow down your search

  6. If you want to see Quaranthings in a specific category, just navigate to that category's page

  7. To take an in depth look at a Quaranthing, click on the Quaranthing card. On the Quaranthing page, you can see other images of the Quaranthing, add it to your cart, leave a review, or see related items

  8. To find others in the Quarangivers community, navigate to the Quarangivers page

  9. To personalize your quarangiver profile, go to edit profile to add a profile pic

  10. To list your own Quaranthing, go to Post Quaranthings

  11. Coming Soon...

    • Responsive layout
    • Search bar

Logic Behind Quaranthings

  • OrderItem Model & Cart
    • Needed to create OrderItem model separate from Product model (but essentially serving same purpose) to store desired quantity for product
    • There is also no cart object. Simply, the cart is the only unordered order (ordered = False) associated with a user
    • If no unordered orders exist, a new one is created when a user adds an item to the cart
    class Order(models.Model):
        products = models.ManyToManyField(OrderItem)
        user = models.ForeignKey(User, related_name = "orders", on_delete = models.CASCADE)
        ordered = models.BooleanField(default=False)
        total = models.DecimalField(max_digits=8, decimal_places=2)
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)
    class OrderItem(models.Model):
        product = models.ForeignKey(Product, on_delete=models.CASCADE)
        quantity = models.IntegerField(default=1)
        created_at = models.DateTimeField(auto_now_add=True)
        updated_at = models.DateTimeField(auto_now=True)
  • Register/Login/Change Password validators
    • Worked with datetime to ensure only users 13 and older can sign up for an account (enables giving user promotional deals when it's their birthday in the future)
    • Used EMAIL_REGEX to verify proper email format
    • Used bcrypt to encrypt user password
    class UserManager(models.Manager):
        def register_validator(self, postData):
            errors = {}
            try:
                birthdate = datetime.strptime(postData["birthday"], '%Y-%m-%d').date()
            except ValueError:
                birthdate = date.today()
            EMAIL_REGEX = re.compile(r'^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9._-]+\.[a-zA-Z]+$')
            if len(postData['first_name']) < 2:
                errors['first_name'] = "First name must be at least 2 characters!"
            if len(postData['last_name']) < 2:
                errors['last_name'] = "Last name must be at least 2 characters!"
            if (date.today()-birthdate).days < 4745: #365 * 13
                errors["birthday"] = "Your need to be at least 13 years old to create an account!"
            if birthdate >= date.today():
                errors["birthday"] = "Your birthday needs to be in the past!"
            if not EMAIL_REGEX.match(postData['email']):
                errors['email'] = "Invalid email address!"
            if User.objects.filter(email = postData['email'].lower()).all().count() > 0:
                errors['email'] = "An account already exists with this email address!"
            if len(postData['password']) < 8:
                errors['password'] = "Password must be at least 8 characters!"
            if postData['password'] != postData['password_conf']:
                errors['password'] = "Your passwords don't match!"
            return errors
        def login_validator(self, postData):
            errors = {}
            EMAIL_REGEX = re.compile(r'^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9._-]+\.[a-zA-Z]+$')
            if not EMAIL_REGEX.match(postData['email']):
                errors['email'] = ("Invalid email address!")
                return errors
            lower_email = postData['email'].lower()
            user = User.objects.filter(email=lower_email) 
            if user:
                logged_user = user[0] 
                if not bcrypt.checkpw(postData['password'].encode(), logged_user.password.encode()):
                    errors["password"] = "Incorrect password!"
            else:
                errors["email"] = "This email has not been registered!"
            return errors
        def password_validator(self, postData):
            errors = {}
            lower_email = postData['email'].lower()
            user = User.objects.filter(email=lower_email)[0]
            if not bcrypt.checkpw(postData['old_pw'].encode(), user.password.encode()):
                errors["old_pw"] = "Your previous password is incorrect!"
            if len(postData['new_pw']) < 8:
                errors['new_pw'] = "New password must be at least 8 characters!"
            if postData['new_pw_conf'] != postData['new_pw']:
                errors['new_pw_conf'] = "Your new passwords don't match!"
            return errors
  • Add to Cart function
    • Retrieve User cart and desired item to be added to cart
    • If the product already exists in the cart, add the newly inputted quantity to the quantity already in the cart
    • Otherwise, create a new OrderItem object linked to this product and add it to the cart
    def add_to_cart(request, num):
        if request.method == "POST":
            user = User.objects.filter(email = request.session['logged_user']).all().first()
            #if user does have a cart, find it. Otherwise create a new cart
            if Order.objects.filter(user = user).filter(ordered = False).all().count() > 0:
                cart = Order.objects.filter(user = user).filter(ordered = False).all().first()
            else:
                cart = Order.objects.create(user = user, total = 0)
            
            product = Product.objects.get(id = num)
    
            
            exists = False
            #if product to be added to cart already exists in cart
            for item in cart.products.all():
                if item.product ==  product:
                    item.quantity += int(request.POST['quantity'])
                    item.save()
                    cart.total += int(request.POST['quantity']) * item.product.price
                    cart.save()
                    exists = True
            if not exists:
                new_item = OrderItem.objects.create(product = product, quantity = request.POST['quantity'])
                cart.products.add(new_item)
                cart.total += Decimal(new_item.quantity) * Decimal(new_item.product.price)
                cart.save()
            return redirect('/users/cart')
        else:
            return redirect('/quaranthings/{}'.format(num))

About

Social e-commerce site allowing users to "purchase" appointments or DIY items from friends for quarantine activities to do together

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published