我想在Django中创建一个嵌套对象模型。 例如
学生:
{
name: 'Tom',
age: 18,
contact: {
phone_num: 12345678,
email: tom12345678@gmail.com
}
}
如何创建它?我尝试使用抽象模型,但这不是我的需要。
class Contact(models.Model):
phone_num = models.IntegerField()
email = models.TextField()
class Meta:
abstract = True
class Student(Contact):
name = models.TextField()
age = models.IntegerField()
当我另存为:
student = Student(name='Tom', age=18, phone_num=12345678, email=tom12345678@gmail.com)
它返回:
{
name: 'Tom',
age: 18,
phone_num: 12345678,
email: tom12345678@gmail.com
}
如何在联系人下放置phone_num和电子邮件?
答案 0 :(得分:0)
对于框架来说,返回这样的结果是正常的,因为这是它与这类关联(使用抽象模型)一起工作的默认方式。当您从抽象(abstract = true
)模型继承时,对于您的情况-Contact
,子级会自动“获取”其所有属性。
如果您想在Contact
和Student
之间建立嵌套连接,则可能需要one to one relationship。
class Contact(models.Model):
phone_num = models.IntegerField()
email = models.TextField()
# Contact now stops being abstract
# because we use it for relationship
class Student(models.Model):
name = models.TextField()
age = models.IntegerField()
contact = models.OneToOneField(Contact)
# ____________________^
考虑到这一点,您现在可以将模型另存为:
contact = Contact(phone_num=12345678, email='tom12345678@gmail.com')
student = Student(name='Tom', age=18, contact=contact)
最后,我们写的最后一行的结果将是您想要的结果:
{
name: 'Tom',
age: 18,
contact: {
phone_num: 12345678,
email: 'tom12345678@gmail.com'
}
}
编辑:
pip install django-rest-framework
然后将其添加到settings.py
在serializers.py
中创建序列化器:
from rest_framework import serializers
from .models import Contact, Student
class ContactSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
fields = ('id', 'email', 'phone_num')
class StudentSerializer(serializers.ModelSerializer):
contact = ContactSerialiezr()
# Here is where the magic happens
# You use *nested serialization* to get the desired result
class Meta:
model = Student
fields = ('id', 'name', 'age', 'contact')
最后,将您的对象序列化为JSON:
>>> contact = Contact(phone_num=12345678, email='tom12345678@gmail.com')
>>> student = Student(name='Tom', age=18, contact=contact)
>>> serializer = StudentSerialize(student)
>>> serializer.data
# {
# 'id': 1,
# 'name': 'Tom',
# 'age': 18,
# 'contact': {
# 'id': 1,
# 'email': 'tom12345678@gmail.com',
# 'phone_num': 12345678
# }
# }
有关嵌套序列化-here的更多信息。
答案 1 :(得分:0)
您的示例是一种称为Abstract class inheritance的继承。这样,您将创建一个包含来自父级和子级所有字段的模型。
如果需要两个不同的表,只需使用与Contact
和class Student(Contact):
name = models.TextField()
age = models.IntegerField()
contact = models.OneToOneField(Contact, on_delete=models.CASCADE)
class Contact(models.Model):
phone_num = models.IntegerField()
email = models.TextField()
相关的ForeignKey。您有几种方法:
class Student(Contact):
name = models.TextField()
age = models.IntegerField()
contact = models.ForeignKey(Contact, on_delete=models.CASCADE)
class Contact(models.Model):
phone_num = models.IntegerField()
email = models.TextField()
class Student(Contact):
name = models.TextField()
age = models.IntegerField()
contacts = models.ManyToManyField(Contact)
class Contact(models.Model):
phone_num = models.IntegerField()
email = models.TextField()
class Student(Contact):
name = models.TextField()
age = models.IntegerField()
class Contact(models.Model):
phone_num = models.IntegerField()
email = models.TextField()
student = models.ForeignKey(Student, related_name="contacts")
Future<int> addShoppingList(String listName) async {
var dbClient = await db;
String now = new DateTime.now().toString();
await dbClient.transaction((txn) async {
int res = await txn.rawInsert("insert into lists(list_name,list_created_at) values(\'$listName\',\'$now\')");
print('result of adding a new shopping list: $res');
return res;
});
List<Map> resList = await dbClient.rawQuery("select list_id from lists where list_name=\'$listName\'");
if (resList.length > 0) {
return resList[0]['list_id'];
}
return 0;
//await dbClient.rawInsert("insert into lists(list_name,list_created_at) values(\'$listName\',\'$now\')");
}
Future<int> addShoppingListItems(int listId, Map<String,String> listItems) async {
var dbClient = await db;
int res = 0;
listItems.forEach((itemName, quantity) async{
int itemId = await getItemId(itemName);
print('adding item $itemName with id $itemId');
await dbClient.transaction((txn) async {
res = await txn.rawInsert("insert into list_items values($listId,$itemId,\'$quantity\')");
print('result of adding item in list_items: $res');
});
return res;
});
return 0;
}
Future<int> addItemsToShoppingList(String listName, Map<String,String> listItems) async {
int listId = await getListId(listName);
if (listId == 0) {
listId = await addShoppingList(listName);
print('got list id of $listId after adding new list');
}
print('in additemstoshoppinglist list id: $listId');
print('in additemstoshoppinglist ${listItems.toString()}');
int res = await addShoppingListItems(listId, listItems);
print('result after adding item in addItemsToShoppingList: $res');
return res;
}