简体   繁体   English

如何使用外键 django 显示来自父 model 的数据

[英]How to display data from parent model using foreign key django

I want to display the child model data with the parent model data as well in a queryset.我想在查询集中显示子 model 数据和父 model 数据。

This is my models in model.py这是我在 model.py 中的模型

class Shareholders(models.Model):
    sharehold_IC = models.CharField(primary_key=True, unique=True, validators=[RegexValidator(r'^\d{12,12}$'), only_int], max_length=12)
    sharehold_name = models.CharField(max_length=100, null=True)
    sharehold_email = models.CharField(max_length=50, null=True, unique=True)
    sharehold_address = models.TextField(null=True, blank=True)
    password = models.CharField(max_length=100)

    def __str__(self):
        return self.sharehold_name

class Meeting(models.Model):

    MEETING_STATUS = (
        ('Coming Soon', 'Coming Soon'),
        ('Live', 'Live'),
        ('Closed', 'Closed')

    )
    meeting_ID = models.CharField(primary_key=True, max_length=6, validators=[RegexValidator(r'^\d{6,6}$')])
    meeting_title = models.CharField(max_length=400, null=True)
    meeting_date = models.DateField()
    meeting_time = models.TimeField()
    meeting_desc = models.CharField(max_length=500, null=True)

    meeting_status = models.CharField(max_length=200, null=True, choices=MEETING_STATUS)
    date_created = models.DateTimeField(default=timezone.now, null=True)
    


    def __str__(self):
        return self.meeting_ID


class Question(models.Model):
    question_ID = models.AutoField(primary_key=True)
    question = models.CharField(max_length=400, null=True)
    meeting_id = models.ForeignKey(Meeting, on_delete=CASCADE)
    shareholder_IC = models.ForeignKey(Shareholders_Meeting, on_delete=CASCADE, related_name='shareholder_ic')
    date_created = models.DateTimeField(default=timezone.now, null=True)


    def __str__(self):
        return str(self.meeting_id)

I try to display all the data from the Question model with the shareholders details such as sharehold_name from the Shareholders model. This is how I try to do in Views.py .我尝试显示问题model 中的所有数据以及股东详细信息,例如股东model 的sharehold_name 。这就是我在Views.py中尝试做的事情。

Views.py视图.py

def getMessages(response, meeting_id):
    meeting = Meeting.objects.get(meeting_ID=meeting_id)
    questions = Question.objects.filter(meeting_id=meeting.meeting_ID)
    # print(list(questions.values('shareholder_IC_id')))
    for i in questions:
        print(i.shareholder_ic.all())
    
    return JsonResponse({"questions":list(questions.values())})

But somehow I got this error AttributeError: 'Question' object has no attribute 'shareholder_ic' .但不知何故我得到了这个错误AttributeError: 'Question' object has no attribute 'shareholder_ic' I want to get the result like this:我想得到这样的结果:

{'question_ID': 141, 'question': "I'm good. How are you?", 'meeting_id_id': '731404', 'shareholder_IC_id': '122311221231', 'date_created': datetime.datetime(2021, 10, 7, 3, 40, 12, 160029, tzinfo=<UTC>), 'sharehold_name':'John Steve', 'sharehold_email':'john@gmail.com'}

How do I fix this or is there any other way to display the data?我该如何解决这个问题,或者有其他方法可以显示数据吗? Thanks in advance提前致谢

You must use backward relations您必须使用向后关系

questions = Question.shareholder_ic.filter(meeting_id=meeting.meeting_ID)

Do not touch it on the object不要在object上碰它

For other settings, create the required query set in manager对于其他设置,在管理器中创建所需的查询集

To begin with, you're not using the related_name attribute in your Question model correctly.首先,您没有正确使用Question related_name中的 related_name 属性。 It's not to use an alternative name to refer to the related model, the opposite, it's the name you want to use to refer to the Question model from the related model, Shareholders in your case.这不是使用替代名称来指代相关的 model,相反,它是您要用来指代来自相关 model 的Question model 的名称,在您的案例中是Shareholders You have to remake your model:你必须重新制作你的 model:

class Question(models.Model):
    question_ID = models.AutoField(primary_key=True)
    question = models.CharField(max_length=400, null=True)
    meeting_id = models.ForeignKey(Meeting, on_delete=CASCADE)
    shareholder_IC = models.ForeignKey(Shareholders_Meeting, on_delete=CASCADE, related_name='questions')
    date_created = models.DateTimeField(default=timezone.now, null=True)


    def __str__(self):
        return str(self.meeting_id)

Then, in your views.py you need to use the correct attribute name in the Question model, which is shareholders_IC :然后,在您的views.py中,您需要在Question model 中使用正确的属性名称,即shareholders_IC

def getMessages(request, meeting_id):  # <- Shouldn't the first param be request?
    meeting = Meeting.objects.get(meeting_ID=meeting_id)
    # No need to use meeting.meeting_ID here, you can use the meeting instance
    questions = Question.objects.filter(meeting_id=meeting)
    for i in questions:
        print(i.shareholder_IC)  # <- No .all(), a question has only one shareholder
    
    return JsonResponse({"questions":list(questions.values())})

However, to achieve what you want, you should either use Django REST Framework, or serialize yourself the different instances that you'll get:但是,要实现您想要的效果,您应该使用 Django REST Framework,或者自己序列化您将获得的不同实例:

def getMessages(request, meeting_id):
    meeting = Meeting.objects.get(meeting_ID=meeting_id)
    questions = Question.objects.filter(meeting_id=meeting)
    questions_list = []
    for i in questions:
        questions_list.append(
            {
                "question_ID": i.question_ID,
                "question": i.question,
                "shareholder_IC_id": i.shareholder_IC.shareholder_IC,
                ...
            }
        )
    
    return JsonResponse(questions_list)

I would recommend two main things:我会推荐两个主要的东西:

  1. Learn about relationships in Django and how to represent them in your models.了解 Django 中的关系以及如何在您的模型中表示它们。 You shouldn't have an attribute meeting_id , for example, in your Question .例如,您不应该在Question中有属性meeting_id Although internally the id is indeed being used to query the Meeting , the attribute has a relationship to the model, not to the ID.虽然在内部确实使用 id 来查询Meeting ,但该属性与 model 有关系,而不是 ID。
  2. Use DRF.使用 DRF。 It will really help you a lot.它真的会对你有很大帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM