Improving on 3.0.0 / adding productorder link based on slug

This commit is contained in:
Nico Schottelius 2022-01-15 00:26:35 +01:00
parent d3b6d28ae6
commit 8952ef0b3a
9 changed files with 178 additions and 8 deletions

View File

@ -15,6 +15,40 @@ machine. Use `kubectl get nodes` to verify minikube is up and running.
## Versions
#### 3.0.0
#### Future (unplanned)
* When/where to add timeframe constraints
* Timeframe slug-or-id
* Maybe slug and backlink to avail products
* Timeframe in product
* Should a product define list of time frames AND resources?
* Then can do autoselect on <resources x timeframes> and only show
complete ones
* resources are also timeframe bound
* name != unique (?)
* Can we filter drop down in admin?
* yes: ModelAdmin.formfield_for_manytomany(db_field, request, **kwargs)¶
* resources should have a slug
* can be used as an identifier and non unique names
#### 3.0.2 (planned)
* Add basic validation to ordering
#### 3.0.1 (planned)
* Show products [done]
* Link to ProductOrderForm [done]
* Continue to resources / add resources
* Confirm & create
#### 3.0.0 (2022-01-14)
* Introduce ProductOrderView
## Pre-Production requirements
* Products need to ensure *all* resources are consistent for different timeframes
* Products cannot have same resource linked twice in same timeframe

View File

@ -0,0 +1,18 @@
# Generated by Django 4.0 on 2022-01-14 22:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0004_auto_20220102_2020'),
]
operations = [
migrations.AddField(
model_name='product',
name='slug',
field=models.SlugField(null=True),
),
]

View File

@ -0,0 +1,28 @@
# Generated by Django 4.0 on 2022-01-14 23:25
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0005_product_slug'),
]
operations = [
migrations.AddField(
model_name='resource',
name='slug',
field=models.SlugField(null=True, unique=True),
),
migrations.AlterField(
model_name='product',
name='slug',
field=models.SlugField(null=True, unique=True),
),
migrations.AlterField(
model_name='resource',
name='name',
field=models.CharField(max_length=128),
),
]

View File

@ -1,6 +1,8 @@
from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
from django.urls import reverse
class Currency(models.Model):
name = models.CharField(max_length=128, unique=True)
@ -43,7 +45,8 @@ class PricePerTime(models.Model):
return f"{self.price} {self.currency.short_name}/{self.timeframe}"
class Resource(models.Model):
name = models.CharField(max_length=128, unique=True) # CPU, RAM
slug = models.SlugField(null=True, unique=True) # primary identifier
name = models.CharField(max_length=128, unique=False) # CPU, RAM
unit = models.CharField(max_length=128) # Count, GB
minimum_units = models.FloatField(null=True, blank=True) # might have min
maximum_units = models.FloatField(null=True, blank=True) # might have max
@ -84,12 +87,16 @@ class Product(models.Model):
"""
name = models.CharField(max_length=128, unique=True)
slug = models.SlugField(null=True, unique=True)
# textconfig = models.ManyToManyField(ProductTextConfiguration)
# textfieldconfig = models.ManyToManyField(ProductTextFieldConfiguration)
resources = models.ManyToManyField(Resource, blank=True)
def get_absolute_url(self):
return reverse('product-detail', kwargs={'slug' : self.slug})
def __str__(self):
return self.name

View File

@ -0,0 +1,10 @@
<h1>{{ object.name }}</h1>
<form method="post" >
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Buy">
</form>
HERE we show a link to <a href="{{ productorder }}">order</a>.

View File

@ -0,0 +1,24 @@
<h1>Select Product</h1>
<h2>Product Order</h2>
<ul>
{% for product in object_list %}
{% if product.slug %}
<li>
<a href="{{ product.get_absolute_url }}">{{ product.name }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
<h2>Product List</h2>
<ul>
{% for product in object_list %}
{% if product.slug %}
<li>
<a href="{{ product.get_absolute_url }}">{{ product.name }}</a>
</li>
{% endif %}
{% endfor %}
</ul>

View File

@ -1,4 +1,7 @@
<form method="post">{% csrf_token %}
Ordering a {{ product }} instance
<form method="post" >
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
<input type="submit" value="Next">
</form>

View File

@ -1,8 +1,49 @@
from django.shortcuts import render
from django.shortcuts import render, get_object_or_404
from django.urls import reverse
from django.views.generic.edit import CreateView
from .models import ProductOrder
from django.views.generic.base import TemplateView
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from .models import *
class ProductOrderView(CreateView):
model = ProductOrder
fields = ['product', 'resources' ]
fields = ['resources']
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['product'] = get_object_or_404(Product, slug=self.kwargs['product'])
print(context)
print(self.kwargs)
return context
class ProductDetailView(DetailView):
model = Product
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['productorder'] = reverse('product-order', kwargs={'product': self.object.slug })
return context
class ProductListView(ListView):
model = Product
class ProductSelectView(CreateView):
model = ProductOrder
fields = ['product' ]
class Yearly(TemplateView):
template_name = "app/config_product.html"
def get_context_data(self, **kwargs):
context = super(Yearly, self).get_context_data(**kwargs)
context['current_year'] = self.current_year
context['current_month'] = self.current_month
return context

View File

@ -19,5 +19,10 @@ from app import views as appviews
urlpatterns = [
path('admin/', admin.site.urls),
path('order', appviews.ProductOrderView.as_view())
path('order', appviews.ProductSelectView.as_view()),
path('order/<slug:product>/', appviews.ProductOrderView.as_view(), name='product-order'),
path('order/<slug:product>/<slug:timeframe>/', appviews.ProductOrderView.as_view(), name='product-order'),
path('product/', appviews.ProductListView.as_view()),
path('product/<slug:slug>/', appviews.ProductDetailView.as_view(), name='product-detail')
]