【问题标题】:django models-design: "ptr field is required"django 模型设计:“ptr 字段是必需的”
【发布时间】:2019-02-04 20:28:36
【问题描述】:

我正在使用 Python 3.6+PostgreSQL 10+最新的 Django 和 DjangoRestFRamework。我有以下模型,其中几个模型继承自一个类,该类是另一个类的 ForeignKey(一对多)。

class Voteable(models.Model):
      Voteable_id = models.BigAutoField(primary_key=True);

class base(Voteable):
    class Meta:
        abstract = False

class traslated_info(models.Model):
    info_about=models.ForeignKey(base)
    info_body=models.TextField()
    info_language=models.CharField(max_length=2)

class A(base):
    A_id=models.BigAutoField(primary_key=True)
    A_field=models.TextField()

class B(base):
    B_id=models.BigAutoField(primary_key=True)
    B_field=models.TextField()
    B_belongs_to=models.ForeignKey(A)

class C(base):
    C_id=models.BigAutoField(primary_key=True)
    C_field=models.TextField()
    C_belongs_to=models.ForeignKey(A)
    C_belongs_to=models.ForeignKey(B)

每当我尝试保存对象 A(通过 curl)时,django 都会说 base_ptr 是必需的。我不知道如何模拟这种情况。最终用户不应创建项目库,然后创建项目 A、B 或 C。我尝试将类库作为抽象类,但抽象类不能是 ForeignKey。我想在创建类 A 时自动创建一个基类。

我想我有两个选择:A) 删除 ForeignKey 并将特定于语言的信息字段存储为 HStoreField。这使得代码在某种程度上依赖于 Postgree。 B) 创建某种例程,在创建子 A 项目 时自动创建父 基本项目(保持一对一关系)。

你有什么推荐的?是否有一些我缺少的 django 简单选项来制作选项 B?我还没有找到这个。谢谢。

【问题讨论】:

  • 模型并不是真正的 OOP 类。模型是数据库关系。继承(除非您使用 AbstractModel)很少是正确的做法

标签: django django-models orm django-rest-framework foreign-keys


【解决方案1】:

在模型 A、B 或 C 中将自动字段作为 primary_key 会导致此错误,因为创建子模型不会级联创建父模型。 我找到了两种解决方法:

  • 将自动字段选项 primary_key 更改为 false 并添加 SILENCED_SYSTEM_CHECKS=['fields.E100']
  • 覆盖 Viewset create 方法:

@transaction.atomic

def create(self,request,*args,**kwargs):
    request.data['base_ptr'] = base.objects.create(user=request.user,created_date=datetime.utcnow()).pk
    return super(viewsets.ModelViewSet,self).create(request,*args,**kwargs)

我会坚持第二个,我很确定会出现更多问题。

【讨论】:

    【解决方案2】:

    如下所示制作你的序列化器,你不需要显式创建基类,它会自动创建。

    class ASerializer(serializers.ModelSerializer):
        class Meta:
            model = A
            read_only_fields = ('base_ptr',)
            fields = '__all__'
    

    【讨论】:

      猜你喜欢
      • 2011-12-02
      • 1970-01-01
      • 2016-10-12
      • 2019-01-07
      • 1970-01-01
      • 2017-06-05
      • 1970-01-01
      • 1970-01-01
      • 2020-10-09
      相关资源
      最近更新 更多