Как я могу решить проблему двойного хранения объектов в базе данных Django?

#json #django #ajax #django-models #youtube-api

#json #django #ajax #django-модели #youtube-api

Вопрос:

Я использую API данных YouTube для создания объекта, но когда я создаю один объект, он создает два объекта — один с соответствующими деталями, а другой пустой. Как я могу решить эту проблему?

перед созданием объекта
введите описание изображения здесь

после создания одного объекта
введите описание изображения здесь

Я пытаюсь использовать следующий код. view.py

 class VideoCreateView(CreateView):
    model = Video
    form_class = VideoForm
    template_name = "videos/video_form.html"
    def form_valid(self, form):
        video = Video()
        video.url = form.cleaned_data['url']
        parse = urllib.parse.urlparse(video.url)
        video_id = urllib.parse.parse_qs(parse.query).get('v')
        if video_id:
            video.youtube_id =video_id[0]
            response = requests.get(f'https://youtube.googleapis.com/youtube/v3/videos?part=snippetamp;id={video_id[0]}amp;key={YOUTUBE_API_KEY}')
            json = response.json()
            items = json["items"]
            assert len(items) <= 1
            if len(items):
                title = items[0]["snippet"]["title"]
                video.title = title
                video.save()
            else:
                title = "N/A"
        return super().form_valid(form)
  

models.py

 class Video(models.Model):

    
    title = models.CharField(max_length=255)
    url = models.URLField()
    youtube_id = models.CharField(max_length=255)
    slug = models.SlugField(blank=True)

    

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("videos:video_detail", kwargs={"slug":self.slug})


        
def video_pre_save_reciever(sender,instance,*args, **kwargs):
    if not instance.slug:
        instance.slug = unique_slug_generator(instance)

pre_save.connect(video_pre_save_reciever,Video)
  

если требуется больше кода, чем указано в комментарии, я обновлю свой вопрос с этой информацией.

Ответ №1:

Представление VideoCreateView наследуется CreateView . CreateView наследует ModelFormMixin , который определяет form_valid метод.

 def form_valid(self, form):
    """If the form is valid, save the associated model."""
    self.object = form.save()
    return super().form_valid(form)
  

Вы сохраняете объект video и вызываете super form_valid, который снова сохраняет форму (в свою очередь, создавая объект модели). Следовательно, вызывая двойное создание. Я предлагаю изменить форму и передать ее в super вместо сохранения вручную.

Другой вариант — наследовать представление с django.views.generic.View помощью . Это позволит избежать сохранения формы.

Я предлагаю вам следовать первому подходу.

Комментарии:

1. Я пробую это, и это все еще сохраняет дважды объект, пожалуйста, ответьте мне изменениями в моем требуемом коде ,

Ответ №2:

Я решил эту проблему, удалив весь код form_valid из представлений и добавив его в модель

 class Video(models.Model):

    
    title = models.CharField(max_length=255)
    url = models.URLField()
    youtube_id = models.CharField(max_length=255)
    slug = models.SlugField(blank=True)

    
    def save(self,*args,**kwargs):
        
        parse = urllib.parse.urlparse(self.url)
        video_id = urllib.parse.parse_qs(parse.query).get('v')
        if video_id:
            self.youtube_id =video_id[0]
            response = requests.get(f'https://youtube.googleapis.com/youtube/v3/videos?part=snippetamp;id={video_id[0]}amp;key={YOUTUBE_API_KEY}')
            json = response.json()
            title = json["items"][0]["snippet"]["title"]
            self.title = title
        super(Video,self).save(*args,**kwargs)