Как сделать конструктор, с помощью которого пользователь может создать шаблон, добавив в него любое поле из модели, включая вложенные поля?
У меня есть 5 сущностей, которые связаны друг с другом. Я успешно описал модели и отношения между ними. Здесь все хорошо.
Но они требуют от меня определенного конструктора, который предполагает, что администратор может в режиме пользователя (в панели администратора, или на любой другой странице) изменить внешний вид чека, который печатается для клиента, не меняя исходного кода программы ( т.е. добавить или убрать поля билета).
Например, пользователь может создать 2 шаблона чека - "обычный" и "уменьшенный".
"Обычная" проверка будет включать название рейса, маршрут, перевозчика, станцию отправления и станцию прибытия, дату отправления и дату прибытия, номер_места и т.д., а "сокращенная" - только название рейса, дату отправления и номер_места
Здесь я кратко опишу модели:
class BusStation(models.Model):
name = models.CharField(max_length=64)
city = models.CharField(max_length=32)
region = models.CharField(max_length=32)
class Carrier(models.Model):
name = models.CharField(max_length=64)
inn_number = models.PositiveBigIntegerField(verbose_name='ИНН', unique=True)
class Itinerary(models.Model):
name = models.CharField(max_length=64)
number = models.CharField(max_length=64)
departure_station = models.ForeignKey(BusStation, related_name='departure_busstations', on_delete=models.CASCADE)
arrival_station = models.ForeignKey(BusStation, related_name='arrival_bus_stations', on_delete=models.CASCADE)
class Voyage(models.Model):
departure_date = models.DateTimeField()
arrival_date = models.DateTimeField()
itinerary = models.ForeignKey(Itinerary, related_name='itineraries', on_delete=models.CASCADE)
bus_station_platform = models.PositiveIntegerField()
class Ticket(models.Model):
TYPE_TICKET = [
('1', '1'),
('2', '2'),
]
passengers_name = models.CharField(max_length=128)
voyage = models.ForeignKey(Voyage, related_name='voyages', on_delete=models.CASCADE)
ticket_number = models.CharField(max_length=32, unique=True)
place_number = models.PositiveSmallIntegerField()
type_ticket = models.CharField(max_length=256, choices=TYPE_TICKET)
Я предполагаю, что мне нужно создать еще один entity и каким-то образом поместить в него поля модели Ticket, но я не уверен, что это правильно.
Любая помощь будет приветствоваться, потому что я застрял на реализации конструктора, так как не понимаю, какой подход использовать для реализации логики.
views.py
from .forms import ReducedTicketForm, RegularTicketForm
class CreateTicketFormView(FormView):
def get_form_class(self):
"""Return the form class to use."""
if self.request.kwargs.get('ticket_type') == 'reduced':
return ReducedTicketForm
return RegularTicketForm
# if there is a need to use different templates,
# adjust the get_template_names() method.
# This is just optional, as you can also use a single template.
def get_template_names(self):
if self.request.kwargs.get('ticket_type') == 'reduced':
return 'reduced_ticket_form.html'
if self.request.kwargs.get('ticket_type') == 'regular':
return 'regular_ticket_form.html'
return super().get_template_names()
# your code ...
forms.py
class ReducedTicketForm(forms.ModelForm):
class Meta:
model = Ticket
fields = ['passengers_name', 'voyage', 'place_number']
exclude = ['created', 'updated']
class RegularTicketForm(forms.ModelForm):
class Meta:
model = Ticket
fields = ['passengers_name', 'voyage', 'ticket_number', 'place_number', 'type_ticket']
exclude = ['created', 'updated']
urls.py
from django.urls import path
from .views import CreateTicketFormView
urlpatterns = [
path(
"ticket/new/<str:ticket_type>/", CreateTicketFormView.as_view(), name="ticket-create"
),
]
template.html
<a href="{% url 'ticket-create' ticket_type='reduced' %}">
Create a reduced ticket
</a>
<a href="{% url 'ticket-create' ticket_type='regular' %}">
Create a regular ticket
</a>
<hr>
{{ form }}