django - 将父对象传递给子对象的 CreateView
问题描述
我正在创建一个仪表板来编辑旅游应用程序。
每次旅行我都有一个子记录,我在其中定义步骤。2 个模型如下所示:
模型.py
class Tour(models.Model):
tour_id = models.CharField(primary_key=True,unique=True, max_length=10)
country = models.ForeignKey(Countries, models.DO_NOTHING, db_column='country')
language = models.ForeignKey(Language, models.DO_NOTHING, db_column='language')
lastupddtm = models.DateTimeField(default=timezone.now)
productid = models.CharField(max_length=50)
title = models.CharField(max_length=50)
description = models.CharField(max_length=100)
descrlong = models.CharField(max_length=1000)
live = models.CharField(max_length=1)
image = models.ImageField(upload_to=upload_tour_image, storage=OverwriteStorage(), blank=True, null=True)
class Meta:
db_table = 'tour'
verbose_name_plural = "tour"
def get_language_flag(self):
return self.language.flag.url
def __str__(self):
return str(self.tour_id) + ' - ' + str(self.title) + ' - ' + str(self.description)
class Toursteps(models.Model):
# tour_id = models.OneToOneField(Tour, models.DO_NOTHING, db_column='tour_id')
tour = models.ForeignKey(Tour, related_name='toursteps', on_delete=models.CASCADE)
step = models.IntegerField(unique=True)
title = models.CharField(max_length=50)
description = models.CharField(max_length=100)
descrlong = models.CharField(max_length=1000)
audiotext = models.TextField()
latitude = models.FloatField()
longitude = models.FloatField()
radius = models.FloatField()
image = models.ImageField(upload_to=upload_tour_step_image, blank=True, null=True)
class Meta:
db_table = 'tourSteps'
verbose_name_plural = "tourSteps"
def __str__(self):
return str(self.tour) + "|" + str(self.step)
创建游览后,我转到详细信息页面。从那里,我可以单击一个链接来为此游览添加一个步骤。这就是问题所在。我将 tour_id 作为变量传递到 url,但我找不到在步骤的 CreateView 中获取它的方法。
网址.py
urlpatterns = [
path('tour/<str:pk>/detail', views.TourDetailView.as_view(), name='tour_detail'),
path('tour/<str:pk>/edit', views.UpdateTourView.as_view(), name='tour_edit'),
path('tour/<str:pk>/remove', views.DeleteTourView.as_view(), name='tour_remove'),
path('tour/<str:tour_id>/step/new', views.CreateTourStepView.as_view(), name='tour_step_new')
]
游览详情视图
<p><a href="{% url 'tour_step_new' tour_id=tour.pk %}"><span class="glyphicon glyphicon-plus"></span></a></p>
视图.py
class CreateTourStepView(LoginRequiredMixin,CreateView):
login_url = '/login/'
redirect_field_name = 'tour_admin/tour_list.html'
success_url = '/'
form_class = TourStepForm
model = Toursteps
def get_context_data(self, **kwargs):
context = super(CreateTourStepView, self).get_context_data(**kwargs)
print(context['tour_id'])
return context
表格.py
class TourStepForm(forms.ModelForm):
class Meta():
model = Toursteps
#fields = '__all__'
exclude = ('tour',)
def form_valid(self, form):
if form.is_valid():
form.instance.tour_id = self.request.GET("tour_id")
form.instance.save()
return HttpResponseRedirect(self.get_success_url())
def get_success_url(self):
return reverse('tour_detail', kwargs={'pk':form.instance.tour_id})
解决方案
首先,您的form_valid()
和get_success_url()
方法属于您的视图,而不是您的表单。
其次,tour_id
传递给视图的kwargs
,它不是查询参数,因此不在self.request.GET
. 你可以在self.kwargs
.
第三,您需要实际从数据库中获取Tour
,而不仅仅是分配tour_id
. 如果我愿意,我可以发布到任何人tour_id
,并且不能保证tour_id
属于实际Tour
对象。如果游览不存在,则返回 404。如果存在,请将其分配给游览步骤。
最后,您不应该分配到和保存form.instance
. 您应该使用 获取实例step = form.save(commit=False)
,然后分配给step
并保存step
。
推荐阅读
- php - 带有 JQuery AJAX 请求的 WordPress codex 错误
- swift - force String to be of a certain struct type in func params in swift
- python - 安装 numpy、matplotlib、pandas、IPython 和 seaborn 时出错
- typescript - 错误消息:“接口只能扩展对象类型或对象类型与静态已知成员的交集”
- c# - 如何为表单设计器上的自定义控件添加 EventHandler?
- r - 功能主成分分数的双图
- reactjs - 有没有在 React 中使用锚标签的特定方法?
- php - 合并长度不等的数组
- python-2.7 - 从 blob 下载文件
- c++ - 如何使用非平凡(POD)类的缓冲区协议实现 pybind11