How To Solve Django ValueError: :Comment.post" должен быть экземпляром "Software"

Я получаю ошибку снова и снова, когда отображаю комментарии к программе. Пожалуйста, подскажите, в чем проблема? Я сделал много попыток, используя get , filter , но ошибка остается той же. Другие ошибки могут появляться при изменении вида комментариев. Пожалуйста, помогите.

    def download(request,slug):   
        app = get_object_or_404 (Software,slug = slug)
        comments= app.comments.filter(active=True).order_by("-created")
        try :
            app  = Software.objects.filter(slug = slug)
        except :
            raise Http404
        new_comment = None
        if request.method == "POST":
        comment_form = CommentForm(data=request.POST)
             if comment_form.is_valid():
                new_comment = comment_form.save(commit=False)
                new_comment.post= app <<<--------------------------->>> here my error
                new_comment.save()
        else:
             comment_form = CommentForm()     
        context ={
            'app' :app,
            'comments': comments,
            'new_comment': new_comment,
            'comment_form': comment_form,       
        }
        return render( request,'download.html',context)

это мои модели:

class Software (models.Model): 
   class Meta :
   verbose_name_plural = 'software'
   ordering = ['created_at']
   category = models.ForeignKey(Categorie,on_delete=models.CASCADE,null=True, related_name="mac")
   category = models.CharField(max_length=150 , null=True,blank=True)
   slug = models.SlugField(blank=True,allow_unicode=True,editable=True)
   title = models.CharField(max_length=50 , null=True)
   requirements = models.CharField(max_length=100 , null=True)
   version = models.CharField(max_length=100 , null=True)
   picture = models.ImageField(upload_to='img_pro' , null=True)
   size = models.CharField(max_length=20 , null=True)
   created_at = models.DateField(auto_now_add=True)
   auther = models.CharField(max_length=100 , null=True)
   download = models.URLField(null=True)



   def __str__(self):
      return self.slug

   def get_absolute_url(self):
      return reverse('download', args=(self.slug,))  


class Comment(models.Model):
   post = models.ForeignKey(Software , on_delete=models.CASCADE ,null=True, related_name='comments')
   name = models.CharField(max_length=80 , null=True)
   email = models.EmailField(max_length=200, blank=True , null=True)
   body = models.TextField( null=True)
   created = models.DateTimeField(auto_now_add=True , null=True)
   active = models.BooleanField(default=False , null=True)
   parent = models.ForeignKey('self', null=True, blank=True, related_name='replies',on_delete=models.CASCADE)

   class Meta:
      ordering = ('created',)

   def __str__(self):
      return 'Comment by {}'.format(self.post)

Ok, obj.objects.filter() всегда возвращает кверисет. Значит, в вашем случае переменная app является кверисетом, а не экземпляром модели Software.

Чтобы убедиться, что переменная app содержит только один единственный экземпляр Software, необходимо использовать obj.objects.get(), что приведет либо к ошибке DoesNotExist, либо к ошибке MultipleObjectsReturned, либо к единственному попаданию в искомый экземпляр модели Software. Здесь вы переходите к поиску с помощью ...objects.get().

Чтобы полностью заменить блок try-except на удобную функцию get_object_or_404() сделайте так:

def download(request,slug):   
    app = get_object_or_404(Software, slug=slug)
    if request.method == "POST":
        comment_form = CommentForm(data=request.POST)
        if comment_form.is_valid():
            new_comment = comment_form.save(commit=False)
            new_comment.comments = app <<<--------------------------->>> here my error
            new_comment.save()
    else:
        comment_form = CommentForm()     
    context ={
        'app' :app,
        'comments': app.comments,
        'new_comment': new_comment,
        'comment_form': comment_form,       
        }
    return render( request,'download.html',context)

Другой проблемой может быть то, что вы ссылаетесь на свои сообщения с помощью comment.post = , но в своей модели Comment вы сказали через related_name, что хотите ссылаться на свои сообщения через comments.

Вам нужно использовать .get() вместо .filter() Запрос для получения объекта, подобного этому...

app  = Software.objects.get(slug = slug) <--- this need to be correct

new_comment = comment_form.save(commit=False)
new_comment.comments = app 
new_comment.save()
Вернуться на верх