【问题标题】:How to set Many to Many field blank=True on both sides in django如何在django的两边设置多对多字段空白=真
【发布时间】:2016-03-07 02:05:12
【问题描述】:

我是 django rest 的新手,今天遇到了一些麻烦: 假设我们有两个模型:

class Tags(models.Model):
    tag_text = models.CharField(name='tag', max_length=30)

class Entries(models.Model):
    entry_header = models.CharField(name='header', max_length=30)
    pub_date = models.DateTimeField(auto_now_add=True)
    entry_text = models.TextField(blank=True, null=True)
    entry_tags = models.ManyToManyField(Tags, related_name='entries', blank=True)

我可以为 Entries 模型设置 blank 属性,但对标签执行相同操作有困难。 这样当我尝试类似的东西时

http --json POST http://127.0.0.1:8000/tags/ tag_text="tag with no entry"

它返回我

"entries": [ This field is required ]

在这种情况下,有什么方法可以创建带有空白“条目”字段的标签对象吗?

提前谢谢你!


...请注意

http --json POST http://127.0.0.1:8000/entries/ header="entry with no tags"

给出期望的响应

在这种情况下,来自 rest_framework 的序列化器也很简单:

class EntriesSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Entries
        fields = ('url', 'header', 'entry_text', 'pub_date', 'entry_tags')

class TagsSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Tags
        fields = ('url', 'tag', 'entries')

这是我们的观点(来自 rest_framework 的视图集以使其更快):

class EntriesView(viewsets.ModelViewSet):
    queryset = Entries.objects.all()
    serializer_class = EntriesSerializer

class TagsView(viewsets.ModelViewSet):
    queryset = Tags.objects.all()
    serializer_class = TagsSerializer

全部通过默认路由器(从 rest_framework.routers 导入 DefaultRouter):

router = DefaultRouter()
router.register(r'entries', views.EntriesView)
router.register(r'tags', views.TagsView)

urlpatterns = [
    url(r'^', include(router.urls)),
]

【问题讨论】:

  • 你能把tag_text = models.CharField(name='tag', max_length=30)设置成tag_text = models.CharField(name='tag', max_length=30, blank=True, null=True)吗?或者您可能需要在 ManyToManyField 上添加 null=True
  • @Caleb_Allen 我尝试将 null=True 添加到 m2m 字段,甚至违反有关 null 属性效果的文档说明......不幸的是它没有工作......
  • 您是否在模型上运行过迁移?可能会有影响。

标签: python django django-models many-to-many django-rest-framework


【解决方案1】:

最终问题似乎出在序列化程序中,而不是模型本身。 字段属性 required=False 应该用来强调如果在模型描述过程中没有指定字段(并且这种方式不能正确序列化),则该字段在对象创建过程中不是必需的。

class TagsSerializer(serializers.HyperlinkedModelSerializer):
entries = EntriesSerializer(many=True, required=False)

class Meta:
    model = Tags
    fields = ('url', 'tag', 'entries')

感谢大家回复并引导我朝着正确的方向前进!

【讨论】:

    【解决方案2】:
    >>> from testapp.models import Tags, Entries
    >>> t = Tags.objects.create(tag = 'TAG')
    >>> t
    <Tags: Tags object>
    

    它对我有用,不是模型,是表单,或者你正在使用的验证器

    【讨论】:

    • 据我从文档中了解到:null 无效,因为没有办法要求数据库级别的关系
    • 你是对的,它有效。你能把剩下的代码贴出来吗?
    • 到目前为止,我遇到了问题,尤其是 http POST。正如您所注意到的,从 shell 创建此类对象没有问题,这样也不是不可能做到的。
    • 你能发布处理这个帖子的视图吗?
    • From: django-rest-framework.org/api-guide/serializers/… "提示:正确匹配超链接表示和您的 URL conf 有时可能有点繁琐。打印 HyperlinkedModelSerializer 实例的 repr 是一种特别有用的方法,可以准确检查哪些视图名称和查找字段,这些关系也应该映射。”
    【解决方案3】:

    您需要在您的TagsSerializer 中设置entries 只读。

    你可以这样做:

    class TagsSerializer(serializers.HyperlinkedModelSerializer):
        entries = EntriesSerializer(many=True, read_only=True)
        class Meta:
            model = Tags
            fields = ('url', 'tag', 'entries')
    

    【讨论】:

    • 好主意!它允许创建对象,但从逻辑上讲,该字段在实际情况下不会是真正的只读。
    猜你喜欢
    • 2021-08-21
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 2013-04-27
    相关资源
    最近更新 更多