为什么我的相关领域不能正常工作? [姜戈]
Why is my my related field not working properly? [Django]
我想实现:
我有 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": "startuptest@gmail.com",
"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 装饰器来关联我发布的标签。
我觉得你应该写 startup.tags.all()
s_tag = TagSerializer(
startup.tags.all(),
many=True,
context={"request": request}
)
我使用@action 装饰器 (https://www.django-rest-framework.org/api-guide/viewsets/) 使 .../startup/<startup:slug>/tags/
可路由,因此我必须使用标签数据命中启动的标签端点,以便将标签与该启动相关联。在我的前端(使用 React)中,我使用了 2 post 个请求来实现相同的目的。我创建了使用启动数据命中启动端点的启动,然后使用标记数据创建了 .../startup/<startup:slug>/tags/
端点。
后来我意识到我必须在以下相关的 api 端点发送标签数据。
我想实现: 我有 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": "startuptest@gmail.com",
"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 装饰器来关联我发布的标签。
我觉得你应该写 startup.tags.all()
s_tag = TagSerializer(
startup.tags.all(),
many=True,
context={"request": request}
)
我使用@action 装饰器 (https://www.django-rest-framework.org/api-guide/viewsets/) 使 .../startup/<startup:slug>/tags/
可路由,因此我必须使用标签数据命中启动的标签端点,以便将标签与该启动相关联。在我的前端(使用 React)中,我使用了 2 post 个请求来实现相同的目的。我创建了使用启动数据命中启动端点的启动,然后使用标记数据创建了 .../startup/<startup:slug>/tags/
端点。
后来我意识到我必须在以下相关的 api 端点发送标签数据。