gpt4 book ai didi

django - 将 Django-taggit 与 django-rest-framework 一起使用,我无法保存我的标签

转载 作者:行者123 更新时间:2023-12-04 03:37:48 25 4
gpt4 key购买 nike

我想弄清楚为什么当我提交表单时,我的标签没有保存在我的数据库中。 django-rest-framework 和 Django-taggit 也很新,我想我做错了什么:)

首先,在使用 rest 框架制作我的 API 之前,我使用了一个通用 View (CreateView 和 UpdateView)来注册/验证我的事件。它工作正常,但我决定更进一步并尝试构建 API,因为我现在正在使用 Angularjs。

现在我的模型事件已创建,但没有我的标签,我有一些错误。我放了一些代码,然后我会描述我的错误。

事件/模型.py

class Event(models.Model):
[...]

title = models.CharField(max_length=245, blank=False)
description = models.TextField(max_length=750, null=True, blank=True)
start = models.DateTimeField()
end = models.DateTimeField()
created_at = models.DateTimeField(editable=False)
updated_at = models.DateTimeField(editable=False)
slug = AutoSlugField(populate_from='title', unique=True, editable=False)
expert = models.BooleanField(choices=MODE_EXPERT, default=0)
home = models.BooleanField(choices=HOME, default=0)
nb_participant = models.PositiveSmallIntegerField(default=1)
price = models.PositiveSmallIntegerField(default=0)
cancelled = models.BooleanField(default=0)

user = models.ForeignKey(User, editable=False, related_name='author')
address = models.ForeignKey('Address', editable=False, related_name='events')
participants = models.ManyToManyField(User, related_name='participants', blank=True, editable=False,
through='Participants')
theme_category = models.ForeignKey('EventThemeCategory', unique=True, editable=False)

tags = TaggableManager(blank=True)

class Meta:
db_table = 'event'

def save(self, *args, **kwargs):
if not self.pk:
self.created_at = timezone.now()
self.updated_at = timezone.now()
super(Event, self).save(*args, **kwargs)
[...]

我正在使用 serializers.HyperlinkedModelSerializer。

api/serializer.py
from taggit.models import Tag

class TagListSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Tag
fields = ('url', 'id', 'name')


class EventSerializer(serializers.HyperlinkedModelSerializer):
address = AddressSerializer()
user = UserSerializer(required=False)
tags = TagListSerializer(blank=True)

class Meta:
model = Event
fields = ('url', 'id', 'title', 'description', 'start', 'end', 'created_at', 'updated_at', 'slug', 'expert','home', 'nb_participant', 'price', 'address', 'user', 'theme_category', 'tags')
depth = 1

api/views/tags_views.py
from rest_framework import generics
from api.serializers import TagListSerializer
from taggit.models import Tag


class TagsListAPIView(generics.ListCreateAPIView):
queryset = Tag.objects.all()
model = Tag
serializer_class = TagListSerializer


class TagsDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
queryset = Tag.objects.all()
model = Tag
serializer_class = TagListSerializer

api/views/events_views.py
class EventListAPIView(generics.ListCreateAPIView):
queryset = Event.objects.all()
model = Event
serializer_class = EventSerializer
paginate_by = 100

def pre_save(self, obj):
"""
Set the object's owner, based on the incoming request.
"""
obj.user = self.request.user
return super(EventListAPIView, self).pre_save(obj)

api/urls.py
    url(r'^events/(?P<slug>[0-9a-zA-Z_-]+)/$', EventDetailAPIView.as_view(), name='event-detail'),

所以首先当我打电话时 /api/events/name-of-my-event API 向我发送带有我的标签的好资源。 GET 方法工作正常。

我在想休息框架遵循查询集。因此,如果我可以获得带有所有标签的资源,为什么当我使用 POST 时我的标签没有注册?

实际上,我对 POST 方法有两个问题:
  • 第一个,如果我发送一个我已经创建的标签,他会向我发送一个错误,指出该标签必须是唯一的。我明白,我不想创建一个新的,我只是希望它与我的对象相关联。当我使用通用 View 时,我没有这个问题(它是通过魔法完成的:) 并且一切正常)
  • 其次,当我尝试创建一个新标签时,我的新事件被保存但没有我的标签。
    您可以看到 angularjs 为我的标签收到的响应......他向我发送了标签的名称,但没有 id、url(超链接)。当我检查我的数据库时,标签尚未创建。
    api response

  • 我想我必须在我的 tags_views 中创建一个自定义 get_queryset(self) 但我不确定。
    我会继续调查。如果有人已经这样做并有一些建议,我会非常 API。谢谢。

    最佳答案

    遇到同样的问题。但我只想通过 TaggableManager 直接保存标签列表(没有 TagListSerializer 和 TagsListAPIView)。我的解决办法是:

    class MyModel(models.Model):
    ...
    tags = TaggableManager(blank=True)

    def get_tags_display(self):
    return self.tags.values_list('name', flat=True)

    class MyModelSerializer(serializers.HyperlinkedModelSerializer):
    ...
    tags = serializers.Field(source='get_tags_display') # more about: http://www.django-rest-framework.org/api-guide/fields#generic-fields
    ...

    class MyModelViewSet(viewsets.ModelViewSet):
    ...
    def post_save(self, *args, **kwargs):
    if 'tags' in self.request.DATA:
    self.object.tags.set(*self.request.DATA['tags']) # type(self.object.tags) == <taggit.managers._TaggableManager>
    return super(MyModelViewSet, self).post_save(*args, **kwargs)

    标签数据的发布数据将是 ['tagA', 'tagB',...],TaggableManager 会处理它。谢谢。

    对于 DRF>3.1,您只需要覆盖 ModelSerializer 类中的 create 和 update :
    class StringListField(serializers.ListField): # get from http://www.django-rest-framework.org/api-guide/fields/#listfield
    child = serializers.CharField()

    def to_representation(self, data):
    return ' '.join(data.values_list('name', flat=True)) # you change the representation style here.


    class MyModelSerializer(serializers.ModelSerializer):
    tags = StringListField()

    class Meta:
    model = models.MyModel

    def create(self, validated_data):
    tags = validated_data.pop('tags')
    instance = super(MyModelSerializer, self).create(validated_data)
    instance.tags.set(*tags)
    return instance

    def update(self, instance, validated_data):
    # looks same as create method

    关于django - 将 Django-taggit 与 django-rest-framework 一起使用,我无法保存我的标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21563726/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com