django models-design:“必须输入ptr字段”

时间:2018-08-30 00:39:31

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

我正在使用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)创建某种例程,该例程在创建子对象时自动创建父项基础项(保留一对一关系)。

您推荐什么?我缺少使选项B缺少的django简单选项吗?我没有找到这个。谢谢。

2 个答案:

答案 0 :(得分:0)

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

  • 将自动字段选项primary_key更改为false并添加 SILENCED_SYSTEM_CHECKS = ['fields.E100']
  • 覆盖视图集 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)

我会坚持第二点,我敢肯定还会出现更多问题。

答案 1 :(得分:0)

使序列化器如下所示,您无需显式创建基类,它将自动创建。

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