I’d like to let the user edit a table inside the create view and also the update view and display it in the detail view. The table is the ‘distancePressures’ variable in the ‘Linker’ model. They should be able to insert rows, delete rows and edit the values in each column (distance, pressure).
Ideally I’d then like to have a dropdown with a few example values for the table, e.g. high resistance, medium resistance and low resistance, which be read into the table as initial values. The other values in the model, such as ‘startPressure’, use django_measurement to let the user set the input units, it would be nice to have the same ability to change the units used in the distance and pressure columns (but not row by row), so the user can enter values in psi and they would be converted in the model to MPa, but no conversion would be necessary if they entered in MPa directly.
The Linker class allows the ManyToMany relationship between the traveller and tube classes, with some extra properties. It started as just the ‘through’ parameter in an ManyToMany variable that initially was a member of Tube, then I wanted to have it as a proper model with views etc that can be created easily by the user.
I’m currently a bit stuck on this (new Django user, my first real project), and have spent a while reading about django-tables2, django-datatables, ajax and jQuery without getting anywhere. The guides I’ve found are either too focused on beginner problems, which were useful when I wanted to displaying a table of known size using <table>
and <tr>
etc but not now, or focus on advanced features like filters, sorting and pagination that aren’t related to this problem. Any help would be appreciated!
# models.py
# Used to model link traveller and tube together
class Linker(models.Model):
startPressure = MeasurementField(
verbose_name = "Start Pressure",
measurement = Pressure,
unit_choices = (("MPa", "MPa"), ("Pa", "Pascals"), ("psi", "psi")),
)
# Guess this is an appropriate data structure, in normal python I'd use
# distances = np.array...
# pressures = np.array...
distancePressures = ArrayField(
ArrayField(models.FloatField(null=True, blank=True)), size=2,
)
traveller = models.ForeignKey('traveller', on_delete=models.CASCADE)
tube = models.ForeignKey('tube', on_delete=models.CASCADE)
@staticmethod
def editable_field_names():
return ('startPressure', 'distancePressures', 'traveller', 'tube')
@staticmethod
def display_field_names():
return Linker.editable_field_names()
Views
# views.py
class LinkerCreateView(LoginRequiredMixin, CreateView):
model = Linker
template_name = 'inker/linker_create.html'
login_url = 'account_login'
success_url = reverse_lazy('linker_list')
fields = Linker.editable_field_names()
class LinkerDetailView(LoginRequiredMixin, DetailView):
model = Linker
template_name = 'linker/linker_detail.html'
login_url = 'account_login'
context_object_name = 'linker'
fields = Linker.display_field_names()
class LinkerUpdateView(LoginRequiredMixin, UpdateView):
model = Linker
template_name = 'linker/linker_update.html'
login_url = 'account_login'
success_url = reverse_lazy('linker_list')
fields = Linker.display_field_names()
Create Form template
<!-- templates/linker/linker_create.html -->
{% extends '_base.html' %}
{% load crispy_forms_tags %}
{% block title %}{{ linker.name }}{% endblock title %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-success" type="submit">Save</button>
</form>
<div class="card-footer text-center text-muted">
<a href="{% url 'linker_list' %}">Back to Linkers</a>
</div>
{% endblock content %}
Detail View template
<!-- templates/linker/linker_detail.html -->
{% extends '_base.html' %}
{% block title %}{{ linker.name }}{% endblock title %}
{% block content %}
<div class="linker-detail">
<h2><a href="">{{ linker.name }}</a></h2>
<p>Tube: <a href="{{ linker.tube.get_absolute_url }}">{{ linker.tube.name }}</a></p>
<p>Traveller: <a href="{{ linker.traveller.get_absolute_url }}">{{ linker.traveller.name }}</a></p>
</div>
<div class="card-footer text-center text-muted">
<a href="{% url 'linker_list' %}">Back to Linkers</a> |
<a href="{% url 'linker_update' linker.pk %}">Edit</a> |
<a href="{% url 'linker_delete' linker.pk %}">Delete</a>
</div>
{% endblock content %}
Update View template
<!-- templates/linkers/linker_update.html -->
{% extends '_base.html' %}
{% load crispy_forms_tags %}
{% block title %}{{ linker.name }}{% endblock title %}
{% block content %}
<h1>Edit</h1>
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-success" type="submit">Save</button>
</form>
<div class="card-footer text-center text-muted">
<a href="{% url 'linker_list' %}">Back to Linkers</a> |
<a href="{% url 'linker_delete' linker.pk %}">Delete</a>
</div>
{% endblock content %}
Base Template
<!-- templates/_base.html-->
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}Artemis{% endblock title %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" href="{% static 'css/base.css' %}">
</head>
<body>
<header>
<!-- Fixed navbar -->
<div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4
mb-3 bg-white border-bottom shadow-sm">
<a href="{% url 'home' %}" class="navbar-brand my-0 mr-md-auto
font-weight-normal">Artemis</a>
<nav class="my-2 my-md-0 mr-md-3">
<a class="p-2 text-dark" href="{% url 'tube_list' %}">Tubes</a>
<a class="p-2 text-dark" href="{% url 'traveller_list' %}">Travellers</a>
<a class="p-2 text-dark" href="{% url 'linker_list' %}">Linkers</a>
<a class="p-2 text-dark" href="{% url 'about' %}">About</a>
{% if user.is_authenticated %}
<a class="p-2 text-dark" href="{% url 'account_logout' %}">Log Out</a>
{% else %}
<a class="p-2 text-dark" href="{% url 'account_login' %}">Log In</a>
<a class="btn btn-outline-primary"
href="{% url 'account_signup' %}">Sign Up</a>
{% endif %}
</nav>
</div>
</header>
<div class="container">
{% block content %}
{% endblock content %}
</div>
<!-- Javascript -->
{% comment %} <script src="{% static 'js/base.js' %}"></script> {% endcomment %}
<!-- JS, Popper.js, and jQuery -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.bundle.min.js" integrity="sha384-1CmrxMRARb6aLqgBO7yyAxTOQE2AKb9GfXnEo760AUcUmFx3ibVJJAzGytlQcNXd" crossorigin="anonymous"></script>
</body>
</html>