Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Pull Request #1

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Python
- Django
- Venv
- Other


### Photos
Expand Down
14 changes: 9 additions & 5 deletions babyshop_app/products/admin.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
from re import search
from django.contrib import admin
from . models import Category, Product
from .models import Category, Product, Review

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display=('name','price')
search_fields=('name',)
list_display = ('name', 'price')
search_fields = ('name',)

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
prepopulated_fields={'slug':('name',)}
prepopulated_fields = {'slug': ('name',)}

@admin.register(Review)
class ReviewAdmin(admin.ModelAdmin):
list_display = ('product', 'user', 'rating', 'comment')
search_fields = ('product__name', 'user__username', 'rating')
39 changes: 19 additions & 20 deletions babyshop_app/products/models.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
from datetime import date
from distutils.command.upload import upload
from email.policy import default
from enum import unique
from pyexpat import model
from unicodedata import name
from django.db import models
from django.conf import settings

class Category(models.Model):
name=models.CharField(max_length=50,null=True)
slug=models.SlugField(max_length=50,unique=True,null=True)
name = models.CharField(max_length=50, null=True)
slug = models.SlugField(max_length=50, unique=True, null=True)

def __str__(self):
return self.name





class Product(models.Model):
name=models.CharField(max_length=80)
description=models.TextField()
image=models.ImageField(upload_to="products/%Y/%m/%d/",default="products/broken-1.png")
date=models.DateField(auto_now=True)
price=models.DecimalField(max_digits=6,decimal_places=2)
category=models.ForeignKey(Category,null=True,on_delete=models.DO_NOTHING)
name = models.CharField(max_length=80)
description = models.TextField()
image = models.ImageField(upload_to="products/%Y/%m/%d/", default="products/broken-1.png")
date = models.DateField(auto_now=True)
price = models.DecimalField(max_digits=6, decimal_places=2)
category = models.ForeignKey(Category, null=True, on_delete=models.DO_NOTHING)

def __str__(self):
return self.name

def __str__(self) -> str:
return self.name
class Review(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
rating = models.PositiveSmallIntegerField()
comment = models.TextField()

def __str__(self):
return f'Review by {self.user.username} for {self.product.name}'
40 changes: 39 additions & 1 deletion babyshop_app/products/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
from django.test import TestCase
from django.contrib.auth.models import User
from .models import Product, Category, Review

# Create your tests here.
class ReviewTestCase(TestCase):
def setUp(self):
# Create a user
self.user = User.objects.create_user(username='testuser', password='testpassword')

# Create a category
self.category = Category.objects.create(name='Electronics', slug='electronics')

# Create a product
self.product = Product.objects.create(
name='Test Product',
description='Test Description',
price=9.99,
category=self.category
)

# Create a review
self.review = Review.objects.create(
user=self.user,
product=self.product,
rating=5,
comment='Great product!'
)

def test_review_content(self):
# Test the review content
self.assertEqual(self.review.user, self.user)
self.assertEqual(self.review.product, self.product)
self.assertEqual(self.review.rating, 5)
self.assertEqual(self.review.comment, 'Great product!')

def test_product_reviews(self):
# Test that the product has the correct review
reviews = self.product.review_set.all()
self.assertIn(self.review, reviews)

# Add more tests as needed for your application
13 changes: 7 additions & 6 deletions babyshop_app/products/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django.urls import path
from . import views

urlpatterns=[
path('',views.product_list,name='products'),
path('categories/<slug:category_slug>',views.product_list,name="products_by_category"),
path('<slug:category_slug>/<int:product_id>',views.product_detail,name="product_detail")

]
urlpatterns = [
path('', views.product_list, name='products'),
path('categories/<slug:category_slug>', views.product_list, name="products_by_category"),
path('<slug:category_slug>/<int:product_id>', views.product_detail, name="product_detail"),
# New URL pattern for adding a review
path('<int:product_id>/add_review/', views.add_review, name="add_review"),
]
36 changes: 9 additions & 27 deletions babyshop_app/products/views.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,11 @@
from datetime import date
from itertools import product
from multiprocessing import context
from unicodedata import category
from django.shortcuts import get_object_or_404, render
from . models import Product
from . models import Category
def product_list(request,category_slug=None):
products=Product.objects.all().order_by('-date')
categories=Category.objects.all().order_by('name')
if category_slug != None:
category_page=get_object_or_404(Category,slug=category_slug)
products=Product.objects.filter(category=category_page)
from django.db import models
from django.contrib.auth.models import User

context={
'products':products,
'categories':categories
}
class Review(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
rating = models.PositiveIntegerField()
comment = models.TextField()


return render(request,'products.html',context=context)
def product_detail(request,category_slug,product_id):
product=Product.objects.get(category__slug=category_slug,id=product_id)
products=Product.objects.all().order_by('-date')
context={
'product':product,
'products':products[0:5],
}
return render(request,'product.html',context)
def __str__(self):
return f"Review by {self.user.username} for {self.product.name}"
79 changes: 54 additions & 25 deletions babyshop_app/templates/product.html
Original file line number Diff line number Diff line change
@@ -1,33 +1,62 @@
{% extends 'partoftemp/_dashboard.html' %}
{% block content %}

<div class="col-md-12 mt-4">
<div class="row g-0 border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative">
<div class="col p-4 d-flex flex-column position-static">
<h3 class="mb-0">{{product.name}}</h3>
<div class="mb-1 text-muted">{{product.price}} &#8378;</div>
<p class="card-text mb-auto">{{product.description}}</p>
<div class="btn btn-primary btn-center">Satın Al</div>
</div>
<div class="col-auto d-none d-lg-block">
<img src="{{product.image.url}}" width="400" height="400" alt="">
<div class="col-md-12 mt-4">
<div class="row g-0 border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative">
<div class="col p-4 d-flex flex-column position-static">
<h3 class="mb-0">{{ product.name }}</h3>
<div class="mb-1 text-muted">{{ product.price }} &#8378;</div>
<p class="card-text mb-auto">{{ product.description }}</p>
<div class="btn btn-primary btn-center">Satın Al</div>
</div>
<div class="col-auto d-none d-lg-block">
<img src="{{ product.image.url }}" width="400" height="400" alt="">
</div>
</div>
</div>

</div>
</div>
<!-- Display existing reviews -->
<div class="product-reviews">
<h4>Product Reviews</h4>
{% for review in product.reviews.all %}
<div class="review">
<strong>{{ review.user.username }}</strong> - <em>{{ review.rating }}/5</em>
<p>{{ review.comment }}</p>
</div>
{% empty %}
<p>No reviews yet.</p>
{% endfor %}
</div>

<!-- Review form -->
<div class="review-form">
<h4>Add a Review</h4>
<form method="post" action="{% url 'add_review' product.id %}">
{% csrf_token %}
<div class="form-group">
<label for="rating">Rating</label>
<input type="number" id="rating" name="rating" min="1" max="5" required>
</div>
<div class="row">
{% for product in products %}
<div class="card" style="width: 18rem;">
<img src="{{product.image.url}}" class="card-img-top" width="300" height="230">
<div class="card-body">
<h5 class="card-title"><a href="{% url 'product_detail' product.category.slug product.id %}">{{product.name}}</a></h5>
<div class="mb-1 text-muted">{{product.price}} &#8378;</div>
<p class="card-text">{{product.description | truncatechars:80}}</p>
<a href="{% url 'product_detail' product.category.slug product.id %}" class="btn btn-primary">Detayına Git</a>
</div>
</div>
{% endfor %}
<div class="form-group">
<label for="comment">Comment</label>
<textarea id="comment" name="comment" rows="4" required></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit Review</button>
</form>
</div>

<div class="row">
{% for product in products %}
<div class="card" style="width: 18rem;">
<img src="{{ product.image.url }}" class="card-img-top" width="300" height="230">
<div class="card-body">
<h5 class="card-title"><a href="{% url 'product_detail' product.category.slug product.id %}">{{ product.name }}</a></h5>
<div class="mb-1 text-muted">{{ product.price }} &#8378;</div>
<p class="card-text">{{ product.description | truncatechars:80 }}</p>
<a href="{% url 'product_detail' product.category.slug product.id %}" class="btn btn-primary">Detayına Git</a>
</div>
</div>
{% endfor %}
</div>

{% endblock %}
{% endblock %}