Skip to content
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
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"python.pythonPath": "/home/django/venv/bin/python",
"python.pythonPath": "/home/karadesh/.pyenv/versions/geekshop/bin/python",
"python.languageServer": "Pylance",
"python.experiments.optOutFrom": ["All"],
"editor.fontFamily": "'JetBrains Mono', 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback'",
Expand Down
2 changes: 2 additions & 0 deletions adminapp/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class Meta:


class ProductCategoryEditForm(forms.ModelForm):
discount = forms.IntegerField(label="скидка", required=False, min_value=0, max_value=90, initial=0)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field_name, field in self.fields.items():
Expand Down
154 changes: 153 additions & 1 deletion adminapp/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,155 @@
from django.conf import settings
from django.test import TestCase
from django.test.client import Client

# Create your tests here.
from authnapp.models import ShopUser


class TestUserManagement(TestCase):
fixtures = [
"mainapp/fixtures/001_categories.json",
"mainapp/fixtures/002_products.json",
"mainapp/fixtures/003_contact_locations.json",
"authnapp/fixtures/admin_user.json",
]

def setUp(self):
self.client = Client()
self.superuser = ShopUser.objects.create_superuser("django2", "django2@geekshop.local", "geekbrains")
self.user = ShopUser.objects.create_user("tarantino", "tarantino@geekshop.local", "geekbrains")
self.user_with__first_name = ShopUser.objects.create_user(
"umaturman", "umaturman@geekshop.local", "geekbrains", first_name="Ума"
)

def test_user_login(self):
response = self.client.get("/")
self.assertEqual(response.status_code, 200)
self.assertTrue(response.context["user"].is_anonymous)
self.assertEqual(response.context["title"], "главная")
self.assertNotContains(response, "Пользователь", status_code=200)
# self.assertNotIn('Пользователь', response.content.decode())

# Set user's data
self.client.login(username="tarantino", password="geekbrains")

# Log in
response = self.client.get("/auth/login/")
self.assertFalse(response.context["user"].is_anonymous)
self.assertEqual(response.context["user"], self.user)

# After log in
response = self.client.get("/")
self.assertContains(response, "Пользователь", status_code=200)
self.assertEqual(response.context["user"], self.user)
# self.assertIn('Пользователь', response.content.decode())

# def test_user_with__first_name_login(self):
# self.client.login(username='umaturman', password='geekbrains')
#
# self.client.get('/auth/login/')
#
# response = self.client.get('/')
# self.assertEqual(response.status_code, 200)
# self.assertIn(self.user_with__first_name.first_name, response.content.decode())
#
# def test_superuser_login(self):
# self.client.login(username='django2', password='geekbrains')
#
# response = self.client.get('/auth/login/')
# self.assertEqual(response.context['user'].is_superuser, True)
#
# response = self.client.get('/')
# self.assertEqual(response.status_code, 200)
# self.assertIn('админка', response.content.decode())

def test_basket_login_redirect(self):
# Test without log in. Must be redirect.
response = self.client.get("/basket/")
self.assertEqual(response.url, "/auth/login/?next=/basket/")
self.assertEqual(response.status_code, 302)

self.client.login(username="tarantino", password="geekbrains")

response = self.client.get("/basket/")
self.assertEqual(response.status_code, 200)
self.assertEqual(list(response.context["basket"]), [])
self.assertEqual(response.context["user"], self.user)
self.assertEqual(response.context["title"], "корзина")
self.assertEqual(response.request["PATH_INFO"], "/basket/")
self.assertIn("Ваша корзина, Пользователь", response.content.decode())

def test_user_logout(self):
# User's data
self.client.login(username="tarantino", password="geekbrains")

# Log in
response = self.client.get("/auth/login/")
self.assertEqual(response.status_code, 200)
self.assertFalse(response.context["user"].is_anonymous)

# Log out
response = self.client.get("/auth/logout/")
self.assertEqual(response.status_code, 302)

# After log out
response = self.client.get("/")
self.assertEqual(response.status_code, 200)
self.assertTrue(response.context["user"].is_anonymous)
self.assertEqual(response.context["title"], "главная")
self.assertNotIn("Пользователь", response.content.decode())

def test_user_register(self):
response = self.client.get("/auth/register/")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context["title"], "регистрация")
self.assertTrue(response.context["user"].is_anonymous)

new_user_data = {
"username": "samuel",
"first_name": "Сэмюэл",
"last_name": "Джексон",
"password1": "geekbrains",
"password2": "geekbrains",
"email": "sumuel@geekshop.local",
"age": "21",
}

# Create new user
response = self.client.post("/auth/register/", data=new_user_data)
self.assertEqual(response.status_code, 302)

new_user = ShopUser.objects.get(username=new_user_data["username"])
# print(new_user, new_user.activation_key)

activation_url = f"{settings.DOMAIN_NAME}/auth/verify/{new_user_data['email']}/{new_user.activation_key}/"

response = self.client.get(activation_url)
self.assertEqual(response.status_code, 200)

self.client.login(username=new_user_data["username"], password=new_user_data["password1"])

# Log in
response = self.client.get("/auth/login/")
self.assertEqual(response.status_code, 200)
self.assertFalse(response.context["user"].is_anonymous)

# Main page check
response = self.client.get("/")
self.assertContains(response, text=new_user_data["first_name"], status_code=200)

def test_user_wrong_register(self):
new_user_data = {
"username": "teen",
"first_name": "Мэри",
"last_name": "Поппинс",
"password1": "geekbrains",
"password2": "geekbrains",
"email": "merypoppins@geekshop.local",
"age": "17",
}

response = self.client.post("/auth/register/", data=new_user_data)
self.assertEqual(response.status_code, 200)
# self.assertFormError(response, form, field, errors, msg_prefix='')
self.assertFormError(response, "register_form", "age", "Вы слишком молоды!")
self.assertIn("Вы слишком молоды!", response.content.decode())
36 changes: 34 additions & 2 deletions adminapp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,29 @@ class ProductCategoryCreateView(LoginRequiredMixin, CreateView):
fields = "__all__"


from django.db.models import F

class ProductCategoryUpdateView(LoginRequiredMixin, UpdateView):
model = ProductCategory
template_name = "adminapp/category_update.html"
success_url = reverse_lazy("admin:categories")
fields = "__all__"
form_class = ProductCategoryEditForm

def get_context_data(self, **kwargs):
context = super(ProductCategoryUpdateView, self).get_context_data(**kwargs)
context["title"] = "категории/редактирование"
return context

def form_valid(self, form):
if "discount" in form.cleaned_data:
discount = form.cleaned_data["discount"]
if discount:
print(f"применяется скидка {discount}% к товарам категории {self.object.name}")
self.object.product_set.update(price=F("price") * (1 - discount / 100))
db_profile_by_type(self.__class__, "UPDATE", connection.queries)

return super().form_valid(form)


class ProductCategoryDeleteView(LoginRequiredMixin, DeleteView):
model = ProductCategory
Expand Down Expand Up @@ -181,4 +193,24 @@ def product_delete(request, pk):
return HttpResponseRedirect(reverse("admin:products", args=[product.category.pk]))

content = {"title": title, "product_to_delete": product, "media_url": settings.MEDIA_URL}
return render(request, "adminapp/product_delete.html", content)
return render(request, "adminapp/product_delete.html", content)

from django.db import connection
from django.db.models.signals import pre_save
from django.dispatch import receiver

def db_profile_by_type(prefix, type, queries):
update_queries = list(filter(lambda x: type in x["sql"], queries))
print(f"db_profile {type} for {prefix}:")
[print(query["sql"]) for query in update_queries]


@receiver(pre_save, sender=ProductCategory)
def product_is_active_update_productcategory_save(sender, instance, **kwargs):
if instance.pk:
if instance.is_active:
instance.product_set.update(is_active=True)
else:
instance.product_set.update(is_active=False)

# db_profile_by_type(sender, 'UPDATE', connection.queries)
13 changes: 10 additions & 3 deletions basketapp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ def basket(request):
return render(request, "basketapp/basket.html", content)


from django.db import connection
from django.db.models import F

@login_required
def basket_add(request, pk):
if "login" in request.META.get("HTTP_REFERER"):
Expand All @@ -26,12 +29,16 @@ def basket_add(request, pk):

if not basket:
basket = Basket(user=request.user, product=product)

basket.quantity += 1
basket.quantity += 1
else:
basket.quantity = F("quantity") + 1

basket.save()

return HttpResponseRedirect(request.META.get("HTTP_REFERER"))
update_queries = list(filter(lambda x: 'UPDATE' in x['sql'], connection.queries))
print(f'query basket_add: {update_queries}')

return HttpResponseRedirect(request.META.get("HTTP_REFERER"))

@login_required
def basket_remove(request, pk):
Expand Down
Binary file modified db.sqlite3
Binary file not shown.
76 changes: 40 additions & 36 deletions geekshop/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@
]

if DEBUG:
INSTALLED_APPS.extend([
"debug_toolbar",
"template_profiler_panel",
"django_extensions",
])
INSTALLED_APPS.extend(
[
# "debug_toolbar",
# "template_profiler_panel",
"django_extensions",
]
)

# Auth model
AUTH_USER_MODEL = "authnapp.ShopUser"
Expand All @@ -66,10 +68,12 @@
"social_django.middleware.SocialAuthExceptionMiddleware",
]

if DEBUG:
MIDDLEWARE.extend([
"debug_toolbar.middleware.DebugToolbarMiddleware",
])
# if DEBUG:
# MIDDLEWARE.extend(
# [
# "debug_toolbar.middleware.DebugToolbarMiddleware",
# ]
# )

ROOT_URLCONF = "geekshop.urls"

Expand Down Expand Up @@ -245,33 +249,33 @@

# INTERNAL_IPS = ["127.0.0.1"]

# Debug tool bar settings
if DEBUG:

def show_toolbar(request):
return True

DEBUG_TOOLBAR_CONFIG = {
"SHOW_TOOLBAR_CALLBACK": show_toolbar,
}

DEBUG_TOOLBAR_PANELS = [
# "ddt_request_history.panels.request_history.RequestHistoryPanel",
"debug_toolbar.panels.versions.VersionsPanel",
"debug_toolbar.panels.timer.TimerPanel",
"debug_toolbar.panels.settings.SettingsPanel",
"debug_toolbar.panels.headers.HeadersPanel",
"debug_toolbar.panels.request.RequestPanel",
"debug_toolbar.panels.sql.SQLPanel",
"debug_toolbar.panels.templates.TemplatesPanel",
"debug_toolbar.panels.staticfiles.StaticFilesPanel",
"debug_toolbar.panels.cache.CachePanel",
"debug_toolbar.panels.signals.SignalsPanel",
"debug_toolbar.panels.logging.LoggingPanel",
"debug_toolbar.panels.redirects.RedirectsPanel",
"debug_toolbar.panels.profiling.ProfilingPanel",
"template_profiler_panel.panels.template.TemplateProfilerPanel",
]
# Debgu tool bar settings
# if DEBUG:

# def show_toolbar(request):
# return True

# DEBUG_TOOLBAR_CONFIG = {
# "SHOW_TOOLBAR_CALLBACK": show_toolbar,
# }

# DEBUG_TOOLBAR_PANELS = [
# # "ddt_request_history.panels.request_history.RequestHistoryPanel",
# "debug_toolbar.panels.versions.VersionsPanel",
# "debug_toolbar.panels.timer.TimerPanel",
# "debug_toolbar.panels.settings.SettingsPanel",
# "debug_toolbar.panels.headers.HeadersPanel",
# "debug_toolbar.panels.request.RequestPanel",
# "debug_toolbar.panels.sql.SQLPanel",
# "debug_toolbar.panels.templates.TemplatesPanel",
# "debug_toolbar.panels.staticfiles.StaticFilesPanel",
# "debug_toolbar.panels.cache.CachePanel",
# "debug_toolbar.panels.signals.SignalsPanel",
# "debug_toolbar.panels.logging.LoggingPanel",
# "debug_toolbar.panels.redirects.RedirectsPanel",
# "debug_toolbar.panels.profiling.ProfilingPanel",
# "template_profiler_panel.panels.template.TemplateProfilerPanel",
# ]

CACHE_MIDDLEWARE_ALIAS = "default"
CACHE_MIDDLEWARE_SECONDS = 120
Expand Down
Loading