【问题标题】:How to query by joining a Django Model with other, on a non unique column?如何通过在非唯一列上将 Django 模型与其他模型连接起来进行查询?
【发布时间】:2019-06-17 18:27:29
【问题描述】:

我的 django 项目的 models.py 文件中有以下模型

from django.contrib.auth.models import AbstractUser
from django.db import models
from django.conf import settings

class CustomUser(AbstractUser):
    pass
    # add additional fields in here

class PDFForm(models.Model):

    pdf_type=models.IntegerField(default=0)
    pdf_name=models.CharField(max_length=100,default='')
    file_path=models.FileField(default='')  

class FormField(models.Model):

    fk_pdf_id=models.ForeignKey('PDFForm', on_delete=models.CASCADE,default=0)
    field_type=models.IntegerField(default=0)
    field_page_number=models.IntegerField(default=0)
    field_x=models.DecimalField(max_digits=6,decimal_places=2,default=0)
    field_y=models.DecimalField(max_digits=6,decimal_places=2,default=0)
    field_x_increment=models.DecimalField(max_digits=6,decimal_places=2,default=0)
    class Meta:
        ordering= ("field_page_number", "field_type")

class UserData(models.Model):

    fk_user_id=models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,default=0)
    field_type=models.IntegerField(default=0)
    field_text=models.CharField(max_length=200,default='')
    field_date=models.DateField()

以下是模型的关联方式

1) pdfform 包含一个 pdf 表单及其在文件系统上的路径

2) 一个 pdfform 中有多个 FormFields。每个字段都有属性,具体讨论的是field_type

3) UserData 模型有用户的数据,所以一个用户在这个表中可以有多行。此模型还具有 field_type 列。

我要查询的是找出 Userdata 模型中存在的所有行,这些行存在于 FormField 模型中(与 field_type 匹配)并且属于特定的 PDFForm。

鉴于 django 模型中的多对多关系不可能在没有唯一字段之间发生,如何进行如下查询

select a.*, b.* from FormField a, UserData b where b.fk_user_id=1 and a.fk_pdf_id=3 and a.field_type=b.field_type

我一直在用细齿梳浏览文档,但显然错过了 django 如何创建连接。什么是使上述sql语句发生的方法,所以我得到了所需的数据集?

【问题讨论】:

    标签: django django-models orm


    【解决方案1】:

    我认为 UserData 缺少与 FormField 的关系,但如果你有这种关系,你可以这样做:

      UserData.objects.filter(
        fk_user_id=1, # Rename this to user, Django wilt automicly create a user_id column
        form_field__in=FormField.objects.filter(
          fk_pdf_id=<your pdfid>  # same as fk_user_id 
        )
      )
    
    

    编辑更新的模型

    当您使用 ForeignKey 时,您不必指定 _id 或 default=0,如果您不想总是填写该字段,最好设置 null=Trueblank=True

    from django.contrib.auth.models import AbstractUser
    from django.db import models
    from django.conf import settings
    
    class CustomUser(AbstractUser):
        pass
        # add additional fields in here
    
    class FieldTypeMixin:
        TYPE_TEXT = 10
        TYPE_DATE = 20
    
        TYPE_CHOISES = [
            (TYPE_TEXT, 'Text'),
            (TYPE_DATE, 'Date'),
        ]
    
        field_type=models.IntegerField(default=TYPE_TEXT, choises=TYPE_CHOISES)
    
    class PDFForm(models.Model):
        pdf_type = models.IntegerField(default=0)
        pdf_name = models.CharField(max_length=100,default='')
        file_path = models.FileField(default='')  
    
    class FormField(models.Model, FieldTypeMixin):
        pdf_form = models.ForeignKey('PDFForm', on_delete=models.CASCADE)
        field_page_number = models.IntegerField(default=0)
        field_x = models.DecimalField(max_digits=6,decimal_places=2,default=0)
        field_y = models.DecimalField(max_digits=6,decimal_places=2,default=0)
        field_x_increment = models.DecimalField(max_digits=6,decimal_places=2,default=0)
    
        class Meta:
            ordering = ("field_page_number", "field_type")
    
    class SubmittedForm(models.Model):
        user = models.ForeignKey(settings.AUTH_USER_MODEL, models.CASCADE)
        pdf_form = models.ForeignKey(PDFForm, models.CASCADE)
    
    class SubmittedFormField(models.Model, FieldTypeMixin):
        submitted_form = models.ForeignKey(SubmittedForm, models.CASCADE)
        form_field = models.ForeignKey(FormField, models.CASCADE, related_name='fields')
    
        field_text = models.CharField(max_length=200,default='')
        field_date = models.DateField()
    
        class Meta:
            unique_together = [
                ['submitted_form', 'form_field']
            ]
    

    【讨论】:

    • 感谢您的回复。向用户数据添加 PDFForm FKin 没有意义。单个用户可以访问多个 PDF,这意味着 Userdatatable 将具有单个用户的多个条目。我正在考虑添加另一个模型,该模型使用外键关联 UserData 和 FormField。
    • 将模型更改为我添加额外模型的建议,知道您可以为每个用户提交尽可能多的表单。并且可以通过关系轻松访问提交的字段
    猜你喜欢
    • 2019-08-27
    • 2019-04-15
    • 2022-01-07
    • 2023-03-19
    • 2015-05-07
    • 2013-09-29
    • 2018-06-17
    • 1970-01-01
    • 2021-10-10
    相关资源
    最近更新 更多