Python 用Django编写合适的数据模型
我正试图写一个Django模型,但当我在文档中读得越来越深入时,我发现我必须考虑太多的事情,我真的对我必须记住的所有考虑事项感到困惑 我最基本的疑问是“当我定义两个类时,我在其中包括对另一个类的引用时…”Python 用Django编写合适的数据模型,python,django,python-3.5,Python,Django,Python 3.5,我正试图写一个Django模型,但当我在文档中读得越来越深入时,我发现我必须考虑太多的事情,我真的对我必须记住的所有考虑事项感到困惑 我最基本的疑问是“当我定义两个类时,我在其中包括对另一个类的引用时…” a) 类a只有一个类B实例 b) A类必须有一个 只有一个B类实例 c) 类A有许多类B实例 d) A类是B类的一种(正如餐厅是 (商业) “…以及在创建这些对象时如何创建/管理这两个类” 我希望有人能更容易地解释。我想,有了这四件事,我也许可以自己写模型了 Django文档仍然是一个很好
- a) 类a只有一个类B实例
- b) A类必须有一个 只有一个B类实例
- c) 类A有许多类B实例
- d) A类是B类的一种(正如餐厅是 (商业)
UserModel
代表A
,UserProfile
代表B
假设我们有一个UserModel
,并且需要另外一个表来保存额外的信息,比如说UserProfile
。我们允许UserProfile
为空。然后我们可以使用OneToOneField
绑定这两个类
模型定义
如何从B访问A,反之亦然
案例b)A类必须有一个且只有一个b类实例
UserModel
代表A
,UserProfile
代表B
对于模型定义,它几乎与案例a)相同。但是我们需要确保B与A共存,因此我们需要删除Blank
和null
。我们必须使用post\u save
hook使suer B也被创建为带有A的保存
模型定义
如何从B访问A,反之亦然
与案例a相同)
案例c)A类有许多B类实例
Author
代表A
,Book
代表B
例如,Author
是一个保存图书作者信息的模型,一个作者可能写零本或多本书,我们将其命名为book
作为模型。(假设每本书只允许一位作者)
如何从B访问A,反之亦然
如果你允许一本书有许多作者,那么我们应该使用ManyToManyField
而不是ForeignKey
。手册
模型定义更改为:
class BookAuthor(models.Model):
author = model.ForeignKey(Author)
book = model.ForeignKey(Book)
publish_at = model.DateTimeField(auto_add=True)
class Book(models.Model):
book_name = models.CharField('name of the book', max_length=50)
# through is used to tell django, we have defined another relationship table to bind Author and Book model.
authors = models.ManyToManyField(Author, through='BookAuthor')
如何从B访问A,反之亦然
案例d)A类是B类的一种类型(餐厅也是一种商业类型)
Place
代表B
,Library
和Restaurant
代表A
例如,我们定义了一个泛型类Place
,而Library
可以是一个场所,与餐厅
相同
模型定义
如何使用A和B
对于上述情况,django将在db中创建一个Place
表,因为它也是一个模型,如果您不知道要创建什么,并将其视为Abstract
类作为其他编程语言,您可以按如下方式重新定义它:
class Place(models.Model):
address = models.CharField('address', max_length=100)
class Meta:
abstract = True
我在Django方面没有任何经验,但建议您仔细阅读有关数据建模的文档,您可能会了解它的实际工作原理。。。。问题是什么?该代码如何不符合您的规范?你在哪里卡住了?请澄清。@Bakuriu问题很简单,“我如何才能编写一个符合所有这些要求的模型”,我陷入了这样的困境,它太复杂了,我真的不知道从哪里开始。我写的代码并不能完成我需要的所有事情。如果你读了这两本书,你会发现它漏掉了。@Bakuriu我写下了我的问题来澄清它。希望现在它能帮助更多。对于a)使用
OneToOneField
,同时将blank
和null
设置为True,对于b)使用OneToOneField
,对于c)使用ForeignKey
,对于d)使用模型继承
。但我认为你不能同时满足这四个要求。非常感谢。这帮了大忙。
from django.db import models
from django.dispatch import receiver
from django.db.models.signals import post_save, pre_save
class UserModel(models.Model):
name = models.CharField('username', max_length=20)
class UserProfile(models.Model):
nickname = models.CharField('nick name', max_length=50)
user = models.OneToOneField(UserModel,on_delete=models.CASCADE)
@receiver(post_save, sender=UserModel)
def create_auth_token(sender, instance=None, created=False, **kwargs):
# This hook is automatically called when the UserModel is created, this is used to make suer UserProfile is also created when UserModel is created.
if created:
UserProfile.objects.create(user=instance)
class Author(models.Model):
name = models.CharField('name of the author', max_length=20)
class Book(models.Model):
book_name = models.CharField('name of the book', max_length=50)
author = models.ForeignKey(Author, related_name='books')
# access B from A
author = Author.objects.get(pk=1)
books = author.books
# first book
book_name = books[0].book_name
# access A from B
book = Book.objects.get(pk=1)
author_name = book.author.name
class BookAuthor(models.Model):
author = model.ForeignKey(Author)
book = model.ForeignKey(Book)
publish_at = model.DateTimeField(auto_add=True)
class Book(models.Model):
book_name = models.CharField('name of the book', max_length=50)
# through is used to tell django, we have defined another relationship table to bind Author and Book model.
authors = models.ManyToManyField(Author, through='BookAuthor')
author = Author.objects.get(pk=1)
first_book_name = author.book_set.order_by('publish_at')[0].book_name
book = Book.objects.get(pk=1)
author_names = [author.name for author in book.author_set.all()]
class Place(models.Model):
address = models.CharField('address', max_length=100)
class Library(Place):
num_of_books = models.IntegerField('NO. of books in the library')
class Restaurant(Place):
restaurant_type = models.CharField('The type of the restaurant', max_length=10)
lib = Library.objects.get(pk=1)
lib.address # get the library address
lib.num_of_books # get the no. of books in this library
rest = Restaurant.objects.get(pk=1)
rest.address # get the restaurant address
rest.restaurant_type # get the restaurant type
class Place(models.Model):
address = models.CharField('address', max_length=100)
class Meta:
abstract = True