как добавить объект foriegnkey и подключить его к объекту post через единственную конечную точку в Django rest Framework - PullRequest
0 голосов
/ 29 мая 2020

models.py

class PostAdvertisment(models.Model):
    # post=models.ForeignKey(Post,on_delete=models.CASCADE,null=True,blank=True)
    created_at=models.DateTimeField(auto_now_add=True)
    title=models.CharField(max_length=255,null=True,blank=True)
    url=models.URLField(null=True,blank=True)
    advertizing_content= models.TextField(null =True ,blank=True)
    def __str__(self):
        return f'{self.title}'
class Post(models.Model):

    # created_at=models.DateTimeField(efault=datetime.now, blank=True)

    created_at=models.DateTimeField(auto_now_add=True)
    author=models.ForeignKey(User,on_delete=models.CASCADE,related_name="post")
    title=models.CharField(max_length=128,null=True,blank=True)
    rate=models.IntegerField(validators=[MinValueValidator(1),MaxValueValidator(5)],default=True,null=True,blank=True)

    # rating=models.IntegerField(null=True,blank=True)
    content=models.TextField(null=True,blank=True)
    review=models.CharField(max_length=250,null=True,blank=True)
    url=models.URLField(null=True,blank=True)
    voters = models.ManyToManyField(settings.AUTH_USER_MODEL,blank=True,related_name="post_voters")
    tags = TaggableManager(blank=True)
    comments=models.ManyToManyField('Comment',blank=True,related_name="comments_post")
    anonymous = models.BooleanField(default=False, blank=True)
    fake = models.BooleanField(default=False, blank=True)

    genuine = models.ManyToManyField(settings.AUTH_USER_MODEL , blank=True, related_name="post_genuines")
    spam = models.ManyToManyField(settings.AUTH_USER_MODEL , blank=True, related_name="post_spames")
    advertisement=models.ForeignKey(PostAdvertisment,on_delete=models.CASCADE,null=True,blank=True)



    def __str__(self):
        return f'{self.content}'
    def get_absolute_url(self):
        return reverse('post:post_detail' , kwargs={'post_id':Post.id})

так вот мой serializers.py

class PostSerializer(TaggitSerializer,serializers.ModelSerializer):
    tags = TagListSerializerField()
    author = serializers.StringRelatedField(read_only=True)
    comments = CommentSerializer(many=True, required=False, read_only=True)
    # title = serializers.CharField()

    advertisement = PostAdvertisementSerializer()
    # advertisement = serializers.SlugRelatedField(
    #     queryset=PostAdvertisment.objects.all(),   
    #     slug_field='advertisement'
    #      )
    # category_name = serializers.CharField(source='advertisement.title')
    class Meta:
        model = Post
        fields = ('id','title','rate','author','content','review','url','tags', 'fake','comments', 'created_at', 'anonymous','advertisement')
    # def create(self, validated_data):
    #     tag = validated_data.pop('advertisement')
    #     tag_instance, created =PostAdvertisment.objects.get_or_create(title=tag)
    #     article_instance = Post.objects.create(**validated_data, advertisement=tag_instance)
    #     return article_instance 
    # def create(self, validated_data):
    #     serializer = self.get_serializer(data=self.request.data)
    #     advertisment =  self.request.data.pop('advertisement')
    #     company_instance = PostAdvertisment.objects.filter(id=advertisment).first()
    #     if not serializer.is_valid():
    #         print(serializer.errors)
    #     data = serializer.validated_data
    #     serializer.save(PostAdvertisment=company_instance)
    #     headers = self.get_success_headers(serializer.data)
    #     return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) 
    def create(self,validated_data):
        advertisement=validated_data.pop('advertisement')


        post=  Post.objects.create(**validated_data)
        for advertise in advertisement:
            PostAdvertisment.object.create(**advertise)
        return post

так что закомментированная часть кода - это то, что я пробовал, разные оценки дали мне разные похищение ошибки, но ни один из них не работал

https://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers

Я следил за этим, но это бесполезно, когда я пытаюсь опубликовать объект, либо это объявление может быть нулевым, либо выдает какую-то странную ошибку в зависимости от метода создания, который я использовал

"advertisement":[]
this is what the error 

{
    "advertisement": {
        "non_field_errors": [
            "Invalid data. Expected a dictionary, but got list."
        ]
    }
}

, когда я изменил его на {}

"advertisement": null

, но когда я попытался передать ему данные

AttributeError at /api/post/
type object 'PostAdvertisment' has no attribute 'object'

Request Method: POST
Request URL: http://localhost:8000/api/post/

я не знаю, как добавлять данные во вложенные объекты

Ответы [ 2 ]

1 голос
/ 30 мая 2020

Во-первых, я не думаю, что реклама должна быть списком. На основе модели Post и PostSerializer, реклама только одна.

После создания PostAdvertisement вам также необходимо обновить post.advertisement / post.advertisement_id. Вот как я думаю:

advertisement=validated_data.pop('advertisement')
post = Post.objects.create(**validated_data)
post.advertisement = PostAdvertisment.objects.create(**advertisement)
post.save()
return post

Вы также можете сначала создать PostAdvertisement, а затем создать Post, чтобы было только 2 запроса db вместо 3:

validated_data["advertisement"] = PostAdvertisment.objects.create(**validated_data["advertisement"])
post = Post.objects.create(**validated_data)
return post
1 голос
/ 29 мая 2020

Вы напечатали с ошибкой, но не PostAdvertisment.object.create (** реклама), а PostAdvertisment.objects.create (** реклама), вы пропустили «s». Советую прочитать ошибку (трассировка).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...