Created: 2020-09-25 Fri 12:39
from django.core import template_loader from django.core.extensions import DjangoContext as Context from django.models.camps import camps from django.utils.httpwrappers import HttpResponse from cciw.apps.cciw.common import Page def index(request): all_camps = camps.get_list(order_by=['-year','number']) years = [camp.year for camp in all_camps] uniqueyears = [] for year in years: if not year in uniqueyears: uniqueyears.append(year) t = template_loader.get_template('camps/index') p = Page(request, title="Camps") c = Context(request, {'camps': all_camps, 'page': p, 'years': uniqueyears}); return HttpResponse(t.render(c))
class AjaxyFormMixin(object): """ A FormView subclass that enables the returning of validation results by JSON if accessed with ?format=json. """ def post(self, request, *args, **kwargs): if request.GET.get('format', None) == 'json': form_class = self.get_form_class() form = self.get_form(form_class) return HttpResponse(python_to_json(form.errors), content_type='text/javascript') else: return super(AjaxyFormMixin, self).post( request, *args, **kwargs )
class AjaxMroFixer(type): def mro(cls): classes = type.mro(cls) # Move AjaxyFormMixin to one before last that # has a 'post' method defined. new_list = [c for c in classes if c is not AjaxyFormMixin] have_post = [c for c in new_list if 'post' in c.__dict__] last = have_post[-1] new_list.insert(new_list.index(last), AjaxyFormMixin) return new_list
(Don't do this!)
Surveys go through milestones: Scoping, Question Development, Compliance, Fielding, Analysis etc.
Question Development is optional
class Survey(models.Model): question_development = models.BooleanField() # lots more fields …
If Survey.question_development is False for a survey, skip the “Question Development” milestone.
Pricing Questions
currency = models.ForeignKey(Currency) min_price = models.DecimalField(max_digits=10, decimal_places=1) max_price = models.DecimalField(max_digits=10, decimal_places=1)
Duplicated lines of code is not the problem
But:
What is going to happen when things change?
1 requirement in N places ⇒ problem
N requirements in 1 place ⇒ problem
# FBV @login_required def account(request): return TemplateResponse(request, 'shop/account.html', { 'user': request.user, }) # CBV class AccountView(LoginRequired, TemplateView): template_name = 'shop/account.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['user'] = self.request.user return context
@login_required def account(request): user = request.user return TemplateResponse(request, 'shop/account.html', { 'user': user, 'orders': user.orders.order_by('-order_date'), }) class AccountView(LoginRequired, TemplateView): template_name = 'shop/account.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) user = self.request.user context['user'] = user context['orders'] = user.orders.order_by('-order_date') return context
@login_required def account(request): orders = request.user.orders.order_by('-order_date') paginator = Paginator(orders, 10) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) return TemplateResponse(request, 'shop/account.html', { 'user': request.user, 'paged_orders': page_obj, })
class AccountView(LoginRequired, ListView): template_name = 'shop/account.html' paginate_by = 10 def get_queryset(self): return self.request.user.orders.order_by('-order_date') def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['user'] = self.request.user return context
Accounts: show a page with basic user info and a list of recent orders, in reverse date order, paginated into 10 items per page.
Products: show a page with a list of products that are for sale, in alphabetical order, paginated into 20 items per page.
# FBV @login_required def account(request): orders = request.user.orders.order_by('-order_date') return TemplateResponse(request, 'shop/account.html', { 'user': request.user, 'in_process_orders': orders.in_process(), 'shipped_orders': orders.shipped()[0:5], })
# CBV class AccountView(LoginRequired, ListView): template_name = 'shop/account.html' def get_queryset(self): return self.request.user.orders.in_process()\ .order_by('-order_date') def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['user'] = self.request.user context['shipped_orders'] = self.request.user.orders.shipped()\ .order_by('-order_date')[0:5] return context
The account page is a list of orders
OR
The account page has a list of orders
Favour object composition over class inheritance.