Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
216 views
in Technique[技术] by (71.8m points)

json - Objects are twicely storing into django database when a single object is created. How to fix this unexpected behavier?

Here i am trying to create a single object with youtube data api , everything is working fine except one thing , when i create a single object it automatically create two objects one with proper details and other one is blank, as shown in pictures , before creating object enter image description here

after creating single object enter image description here

I am trying with the following code. 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=snippet&id={video_id[0]}&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)

if more code is require than tell me in comment , i will update my question with that information.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The view VideoCreateView inherits CreateView. CreateView inherits ModelFormMixin which defines form_valid method.

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

You save the video object and call the super form_valid which saves the form(in turn creating a model object) again. Hence, causing a double creation. I suggest modifying the form and passing it to super instead of manually saving it.

Another option is to inherit the View with django.views.generic.View. This would avoid form save.

I suggest you follow the first approach.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...