Django P3로 구축된 리테일 웹사이트 (2020-02-07)
22888 단어 djangodailynotes
장고:
urls.py에서 어느 것이 먼저 가는지 주의하세요.
app_name = 'boutique'
urlpatterns = [
# show index page
path('', views.IndexView.as_view(), name='index'),
# show a specific item
path('item_<int:item_pk>/', views.ItemDetailView.as_view(), name='item'),
# show categories of products for men or women
path('<slug:gender>/', views.CategoryListView.as_view(), name='show-all'),
# show a specific category for men or women
path('<slug:gender>/cat_<int:category_pk>/', views.CategoryListView.as_view(), name='category'),
# show a specific subcategory under a specific category for men or women
path('<slug:gender>/cat_<int:category_pk>/subcat_<int:subcategory_pk>/', views.CategoryListView.as_view(), name='subcategory'),
]
이 파일에서
item
뒤에 subcategory
를 넣으면 item
보기가 올바른 페이지를 렌더링하지 않습니다.모델 - 성별 선택
아래 예:
class Category(models.Model):
'''Category for men's and women's items'''
gender = models.IntegerField(choices=[
(1, 'Women'),
(2, 'Men'),
], default=1)
name = models.CharField(max_length=100)
description = models.CharField(max_length=300, blank=True)
uploaded_date = models.DateTimeField(
auto_now_add=True, null=True, blank=True)
class Meta():
verbose_name_plural = 'Categories'
def __str__(self):
return self.get_gender_display() + ' ' + self.name
def get_category_url(self):
return reverse('boutique:category', kwargs={'gender': self.get_gender_display(), 'category_pk': self.pk})
이 예에서 주목해야 할 몇 가지 사항은 다음과 같습니다.
*
ListView
는 소문자*
choices
는 튜플choices
를 사용하여 필드 선택에 액세스할 수 있습니다. this에서 자세한 내용def get_absolute_url()의 get_FOO_display()
models.py
from django.urls import reverse
class SomeModel(models.Model):
<---snip--->
# it can be any name you like because it doesn't seem to be inheriting from anything
def get_absolute_url(self):
return reverse('app_name:view_name', kwargs={'key': self.field_name})
# reverse returns a string for href content
URL을 html 태그로 구현할 때 SomeModel이 액세스 가능한지 확인하십시오(반복을 통해 또는 컨텍스트를 통해 전달된 객체임).
*html
<a href="{{ SomeModel.get_absolute_url }}">link</a>
동적 처리 URL: 내가 게시한 SO 질문을 확인하세요.
Mathias의 답변에 따르면 django-middleware-global-request을 설치하지 않으면 불가능합니다.
그런 다음 다음을 수행할 수 있습니다.
from django_global_request.middleware import get_request
class TestModel(models.Model):
...
def get_absolute_url(self):
request = get_request()
if request.GET.get('whatever'):
return ...
else:
return ...
You just need to make sure, you could still access this method without any available request. So make sure it's fail save and has a fallback in case of the absence of a request (like in a shell, upgrade, etc.)
get_context_data(self, **kwargs)의 models.py 및 get_queryset(self) - CCBV
ListView
는 get_queryset()
에서 더 유용합니다. 렌더링할 템플릿에 대한 쿼리 세트를 반환하기 때문입니다. ListView
가 컨텍스트를 통해 자동으로 전달됩니다! _모델이 CBV에 정의되어 있으면
queryset
가 자동으로 실행되고 get_queryset()
를 획득합니다. class SomeView(ListView):
<---snip--->
# context_object_name represents the result of get_queryset()
# you can directly access this from the template even if you do not set context_object_name
context_object_name = 'coobna'
def get_queryset(self):
# if you still need the default functionality of this function
# it's like to inherite from it's superior, instead of writing a whole new function
queryset = super().get_queryset()
# before returning the queryset, you can print(queryset) to debug or for referencing purposes
return queryset.filter(........)
def get_context_data(self, **kwargs):
# inherite the functionality from its 'superior'
context = super().get_context_data(**kwargs)
# now you can add more context to it
new_context = Category.objects.all()
context['new_context'] = new_context
# you can always print out the context for debugging
print(context)
return context
ListView의 예:
class CategoryListView(ListView):
'''display a list of items'''
model = Category
template_name = 'boutique/items.html'
# context_object_name is actually the result of `get_queryset()`
context_object_name = 'category_shown'
# paginate_by = 12
def get_queryset(self):
# get original queryset: Category.objects.all()
qs = super().get_queryset()
# filter men/women
if self.kwargs.get('gender') == 'Women':
qs = qs.filter(gender=1)
elif self.kwargs['gender'] == 'Men':
qs = qs.filter(gender=2)
if self.kwargs.get('category_pk'):
qs = qs.filter(pk=self.kwargs.get('category_pk'))
# print('\nqs= ', qs, '\n')
return qs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# add categories for navbar link texts
context['categories'] = Category.objects.all()
if self.kwargs.get('subcategory_pk'):
context['subcategory_shown'] = get_object_or_404(
SubCategory, pk=self.kwargs.get('subcategory_pk'))
context['item_list'] = Item.objects.filter(
subcategory=self.kwargs.get('subcategory_pk'))
# print('\ncontext with subcat= ', context, '\n')
return context
# Because context_object_name actually represents the result of `get_queryset()`
# Therefore, if context_object_name is set to the same name as the context name
# the following expression can be omitted
# context['category_shown'] = self.get_queryset()
# The benefit of this is you don't need to run get_queryset() again!!
if self.kwargs.get('category_pk'):
context['item_list'] = Item.objects.filter(
category=self.kwargs.get('category_pk'))
# print('\ncontext= ', context, '\n')
return context
CCBV의 상세보기
예시
class ItemDetailView(DetailView):
'''display an individual item'''
model = Item
template_name = 'boutique/item.html'
# no need to specify as default context_object_name depends on the model
# they are actually the same (with lower case first letter)
# context_object_name = 'item'
몇 가지 참고 사항:
### 하지만:
CBV로 전달되는 URL 값(StackO의 체크아웃my question)에 대해 매우 주의해야 합니다.
url.py
urlpatterns = [
path('item_<int:pk>/', views.ItemDetailView.as_view(), name='item'),
]
나는
model.objects.all()
를 사용했기 때문에 작동하지 않았습니다. DetailView가 작동하려면 path('item_<int:item_pk>/'...)
를 전달하거나 <pk>
의 CBV를 지정해야 합니다. docs
Reference
이 문제에 관하여(Django P3로 구축된 리테일 웹사이트 (2020-02-07)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ld8/daily-notes-retail-website-in-russian-p3-2020-02-07-2n5k텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)