Improving on 3.0.0 / adding productorder link based on slug
This commit is contained in:
parent
d3b6d28ae6
commit
8952ef0b3a
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
]
|
|
@ -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),
|
||||
),
|
||||
]
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>.
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue