为什么我的相关领域不能正常工作? [姜戈]

发布于 2025-01-09 13:24:40 字数 4062 浏览 3 评论 0原文

我想达到: 我有 2 个模型标签和启动。

我的 models.py 文件 -

from django.db import models
from django_extensions.db.fields import AutoSlugField
from django.db.models import CharField, TextField, DateField, EmailField, ManyToManyField


class Tag(models.Model):

    name = CharField(max_length=31, unique=True, default="tag-django")
    slug = AutoSlugField(max_length=31, unique=True, populate_from=["name"])

    def __str__(self):
        return self.name


class Startup(models.Model):

    name = CharField(max_length=31, db_index=True)
    slug = AutoSlugField(max_length=31, unique=True, populate_from=["name"])
    description = TextField()
    date_founded = DateField(auto_now_add=True)
    contact = EmailField()
    tags = ManyToManyField(Tag, related_name="tags")

    class Meta:
        get_latest_by = ["date_founded"]

    def __str__(self):
        return self.name

创建启动时,我有一个已创建标签的下拉列表,我想将其与我正在创建的启动相关联。 当我发布数据时 -

{
    "name": "Startup4",
    "description": "TestStartup",
    "contact": "[email protected]",
    "tags": [
        {
            "url": "http://127.0.0.1:8000/api/v1/tag/first-tag/",
            "name": "First Tag",
            "slug": "first-tag"
        },
        {
            "url": "http://127.0.0.1:8000/api/v1/tag/second-tag/",
            "name": "Second Tag",
            "slug": "second-tag"
        },
        {
            "url": "http://127.0.0.1:8000/api/v1/tag/third-tag/",
            "name": "Third Tag",
            "slug": "third-tag"
        }
    ]
}

创建了一个启动但标签字段仍为空。没有相关的标签。

我的serializers.py 文件 -

from rest_framework.serializers import HyperlinkedModelSerializer, PrimaryKeyRelatedField, ModelSerializer
from .models import Startup, Tag


class TagSerializer(HyperlinkedModelSerializer):
    class Meta:
        model = Tag
        fields = "__all__"
        extra_kwargs = {
            "url": {
                "lookup_field": "slug",
                "view_name": "tag-api-detail"
            }
        }


class StartupSerializer(HyperlinkedModelSerializer):
    tags = TagSerializer(many=True, read_only=False)

    class Meta:
        model = Startup
        fields = "__all__"
        extra_kwargs = {
            "url": {
                "lookup_field": "slug",
                "view_name": "startup-api-detail"
            }
        }

我的viewsets.py 文件 -

from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from .serializers import TagSerializer, StartupSerializer
from .models import Tag, Startup
from rest_framework.decorators import action
from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_200_OK, HTTP_204_NO_CONTENT
from django.shortcuts import get_object_or_404


class TagViewSet(ModelViewSet):

    queryset = Tag.objects.all()
    serializer_class = TagSerializer
    lookup_field = "slug"


class StartupViewSet(ModelViewSet):

    serializer_class = StartupSerializer
    queryset = Startup.objects.all()
    lookup_field = "slug"


    @action(detail=True, methods=["HEAD", "GET", "POST"], url_path="tags")
    def tags(self, request, slug=None):
        # relate a Posted Tag
        startup = self.get_object()
        print(startup)
        if request.method in ("HEAD", "GET"):
            s_tag = TagSerializer(
                startup.tags,
                many=True,
                context={"request": request}
            )
            return Response(s_tag.data)

        tag_slug = request.data.get("slug")

        if not tag_slug:
            return Response(
                "Slug of Tag must be specified",
                status=HTTP_400_BAD_REQUEST
            )
        tag = get_object_or_404(Tag, slug__iexact=tag_slug)
        startup.tags.add(tag)
        startup.save()
        return Response(HTTP_204_NO_CONTENT)

我不明白问题出在哪里。我正在使用 @action 装饰器来关联我发布的标签。

I want to acheive:
I have 2 Models Tag and Startup.

my models.py file -

from django.db import models
from django_extensions.db.fields import AutoSlugField
from django.db.models import CharField, TextField, DateField, EmailField, ManyToManyField


class Tag(models.Model):

    name = CharField(max_length=31, unique=True, default="tag-django")
    slug = AutoSlugField(max_length=31, unique=True, populate_from=["name"])

    def __str__(self):
        return self.name


class Startup(models.Model):

    name = CharField(max_length=31, db_index=True)
    slug = AutoSlugField(max_length=31, unique=True, populate_from=["name"])
    description = TextField()
    date_founded = DateField(auto_now_add=True)
    contact = EmailField()
    tags = ManyToManyField(Tag, related_name="tags")

    class Meta:
        get_latest_by = ["date_founded"]

    def __str__(self):
        return self.name

When creating a startup, I have a dropdown list of created Tags which I want to relate to my Startup that I am creating.
When I am posting the data -

{
    "name": "Startup4",
    "description": "TestStartup",
    "contact": "[email protected]",
    "tags": [
        {
            "url": "http://127.0.0.1:8000/api/v1/tag/first-tag/",
            "name": "First Tag",
            "slug": "first-tag"
        },
        {
            "url": "http://127.0.0.1:8000/api/v1/tag/second-tag/",
            "name": "Second Tag",
            "slug": "second-tag"
        },
        {
            "url": "http://127.0.0.1:8000/api/v1/tag/third-tag/",
            "name": "Third Tag",
            "slug": "third-tag"
        }
    ]
}

A startup is created but the tags field remains empty. No Tags are related.

My serializers.py file -

from rest_framework.serializers import HyperlinkedModelSerializer, PrimaryKeyRelatedField, ModelSerializer
from .models import Startup, Tag


class TagSerializer(HyperlinkedModelSerializer):
    class Meta:
        model = Tag
        fields = "__all__"
        extra_kwargs = {
            "url": {
                "lookup_field": "slug",
                "view_name": "tag-api-detail"
            }
        }


class StartupSerializer(HyperlinkedModelSerializer):
    tags = TagSerializer(many=True, read_only=False)

    class Meta:
        model = Startup
        fields = "__all__"
        extra_kwargs = {
            "url": {
                "lookup_field": "slug",
                "view_name": "startup-api-detail"
            }
        }

My viewsets.py file -

from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from .serializers import TagSerializer, StartupSerializer
from .models import Tag, Startup
from rest_framework.decorators import action
from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_200_OK, HTTP_204_NO_CONTENT
from django.shortcuts import get_object_or_404


class TagViewSet(ModelViewSet):

    queryset = Tag.objects.all()
    serializer_class = TagSerializer
    lookup_field = "slug"


class StartupViewSet(ModelViewSet):

    serializer_class = StartupSerializer
    queryset = Startup.objects.all()
    lookup_field = "slug"


    @action(detail=True, methods=["HEAD", "GET", "POST"], url_path="tags")
    def tags(self, request, slug=None):
        # relate a Posted Tag
        startup = self.get_object()
        print(startup)
        if request.method in ("HEAD", "GET"):
            s_tag = TagSerializer(
                startup.tags,
                many=True,
                context={"request": request}
            )
            return Response(s_tag.data)

        tag_slug = request.data.get("slug")

        if not tag_slug:
            return Response(
                "Slug of Tag must be specified",
                status=HTTP_400_BAD_REQUEST
            )
        tag = get_object_or_404(Tag, slug__iexact=tag_slug)
        startup.tags.add(tag)
        startup.save()
        return Response(HTTP_204_NO_CONTENT)

I do not understand where is the problem. I am using @action decorator to relate my POSTed tags.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

澉约 2025-01-16 13:24:40

我认为你应该写startup.tags.all()

s_tag = TagSerializer(
                startup.tags.all(),
                many=True,
                context={"request": request}
            )

I think you should write startup.tags.all()

s_tag = TagSerializer(
                startup.tags.all(),
                many=True,
                context={"request": request}
            )
各自安好 2025-01-16 13:24:40

我使用了 @action 装饰器 (https://www.django-rest- framework.org/api-guide/viewsets/) 使 .../startup//tags/ 可路由,因此我必须点击 的标签端点带有标签数据的启动将标签与该启动相关联。在我的前端(使用 React)中,我使用了 2 个 post 请求来实现相同的效果。我使用启动数据创建了启动端点,然后使用标签数据创建了 .../startup//tags/ 端点。

后来我意识到我必须在以下相关的 api 端点中发送标签数据。

I have used @action decorator (https://www.django-rest-framework.org/api-guide/viewsets/) to make .../startup/<startup:slug>/tags/ routable so the I have to hit the tags endpoint of the startup with the tag data to relate tags with that startup. In my frontend (Using React) I used 2 post requests to acheive the same. I created the startup hitting the startup endpoint with startup data and then .../startup/<startup:slug>/tags/ endpoint with the tag data.

I realized it later that I have to send the tag data in the following related api endpoint.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文