如何创建一个构造函数,用户可以通过从模型中添加任何字段来创建模板,包括嵌套字段?



我有5个相互关联的实体。我已经成功地描述了模型和它们之间的关系。这里一切都很好。

但是它们需要一个特定的构造函数从我,假定管理员可以在用户模式(在管理面板中,或任何其他页面),改变的外观检查打印客户端在不改变程序的源代码(。添加或删除票证字段) .

例如,用户可以创建2个收据模板"regular"one_answers"reduced".

"regular"检查将包括航次名称、行程、承运人、始发站和到达站、始发日期和到达日期、地点号码等,而"缩写"为";将只包含航次名称、departure_date和place_number

我将在这里简要描述模型(models.py)):

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(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)

创建票证的表单非常简单,一切工作正常(forms.py)):

class TicketCreateForm(forms.ModelForm):
class Meta:
model = Ticket
fields = ['passengers_name', 'voyage', 'ticket_number', 'place_number', 'type_ticket']
exclude = ['created', 'updated']
相应地,处理程序也非常简单(views.py)。):
@staff_member_required
def ticket_create(request):
if request.method == 'POST':
form = TicketCreateForm(request.POST)
if form.is_valid():
ticket = form.save(commit=False)
ticket.save()
return render(request, 'tickets/ticket_created.html', {
'ticket': ticket,
})
else:
form = TicketCreateForm()
context = {
'form': form,
}
return render(request, 'tickets/ticket_create.html', context)
我想我需要创建另一个实体然后把票证的字段模型,但我不确定这是否正确。

任何帮助都是受欢迎的,因为我被构造函数的实现卡住了,因为我不知道用什么方法来实现逻辑。

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 }}