Как отобразить данные из родительской модели с помощью внешнего ключа django
Я хочу отобразить данные дочерней модели вместе с данными родительской модели в наборе запросов.
Это мои модели в 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)
Я пытаюсь отобразить все данные из модели Question с подробной информацией об акционерах, такой как sharehold_name из модели Shareholders. Вот как я пытаюсь сделать это в Views.py.
Views.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())})
Но почему-то я получил эту ошибку AttributeError: 'Question' object has no attribute 'shareholder_ic'
.
Я хочу получить результат, подобный этому:
{'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'}
Как это исправить или есть ли другой способ отображения данных? Заранее спасибо
Вы должны использовать обратные связи
questions = Question.shareholder_ic.filter(meeting_id=meeting.meeting_ID)
Не прикасайтесь к предмету
Для других настроек создайте необходимый набор запросов в менеджере
Начнем с того, что вы неправильно используете атрибут related_name
в вашей модели Question
. Это не использование альтернативного имени для ссылки на связанную модель, наоборот, это имя, которое вы хотите использовать для ссылки на модель Question
из связанной модели, Shareholders
в вашем случае. Вы должны переделать свою модель:
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)
Тогда, в вашем views.py
вам нужно использовать правильное имя атрибута в модели Question
, которое является 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())})
Однако, чтобы достичь желаемого, вы должны либо использовать 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)
Я бы рекомендовал две основные вещи:
- Узнайте об отношениях в Django и о том, как представлять их в ваших моделях. Вы не должны иметь атрибут
meeting_id
, например, в вашемQuestion
. Хотя внутренне id действительно используется для запросаMeeting
, атрибут имеет отношение к модели, а не к ID. - Используйте DRF. Это очень поможет вам.