Передача родительского объекта в CreateView для дочернего объекта - PullRequest
0 голосов
/ 03 апреля 2020

Я создаю панель управления для редактирования приложения тура.

За тур у меня есть дочерняя запись, в которой я определяю шаги. Две модели выглядят так:

models.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)

После того, как я создал Тур, я go перехожу на страницу с подробностями. Оттуда я могу нажать на ссылку, чтобы добавить шаг для этого тура. Вот где проблема. Я передаю tour_id как переменную в URL, но не могу найти способ найти его в CreateView шага.

urls.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>

views.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

forms.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})

1 Ответ

1 голос
/ 03 апреля 2020

Во-первых, ваши 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.

...