The previous blog post is about the configuration of the setting.py file database and the relationship between model and database table, the implementation of Bloguser, the Bloguser information into the background database. There are many things in real development that are interconnected, in addition to the display and storage of data, We also need to clarify the relationship between the various data objects. The Django framework defines three relational models:
Onetoone
Onetoone: This correspondence is the simplest, that is, the literal meaning of one to the other. Django uses Onetoonefield to represent this correspondence.
Onetomany
Onetomany (one-to-many): a common relationship, there are a lot of relationships in real life, such as: the relationship between students and books: A student can have a lot of books, but the holder of a book is generally only one. This relationship is also relatively easy to understand, Django uses ForeignKey to represent a one-to-many relationship.
Manytomany
Manytomany (Many-to-many): This is also very common, such as the relationship between the student and the instructor. A student generally has a number of classroom teachers, the classroom teacher also teaches many students. Django uses Manytomanyfield to express many-to-many relationships
This paper mainly focuses on the relationship between the two Onetomany and Manytomany.
1 Add Model
We define a model for the label category (e.g. math, language, programming, etc.), and then define a blog label model. Tag Category objects can have multiple blog tags below (for example, the following categories can be categorized as: C, C++,c#,java,python, etc.), You can have multiple blogs under a blog tag. Then define a blog model, a blog can have multiple tags (this blog post on the two tags of Django and Python);
Edit the definition of the MyBlog file directory models.py
' Tagtype ', ' blogtag ', ' Blog ' three model:
classTagtype (models. Model):#文章大类Del_choices=( (' YES ',' deactivated '), (' NO ',' normal use '),) TypeName=Models. Charfield (' category ', Max_length= -) CreateDate=Models. Datetimefield (' Create Time ', Auto_now_add=True) isdeleted=Models. Charfield (' Remove flag ', Max_length=Ten, default=' NO ', Choices=Del_choices) deletedate=Models. Datetimefield (' Delete Time ', blank=TrueNull=True)def __str__( Self):return Self. TypeNameclassBlogtag (models. Model):#标签子类Del_choices=( (' YES ',' deactivated '), (' NO ',' normal use '),) Tagtype=Models. ForeignKey (Tagtype,on_delete=Models. Set_null,blank=TrueNull=True)#on_delete =models. Set_null The field is empty when the parent record is deleted, keeping the recordTagename=Models. Charfield (' tag name ', Max_length= -) CreateDate=Models. Datetimefield (' Create Time ', Auto_now_add=True) isdeleted=Models. Charfield (' Remove flag ', Max_length=Ten, default=' NO ', Choices=Del_choices) deletedate=Models. Datetimefield (' Delete Time ', blank=TrueNull=True)def __str__( Self):return Self. tagtype.typename+ Self. tagenameclassBlog (models. Model):#博客Title=Models. Charfield (' title ', Max_length= $) tag=Models. Manytomanyfield (Blogtag) content=Models. TextField (' body ', blank=TrueNull=True) author=Models. ForeignKey (Bloguser,on_delete=Models. Set_null,blank=TrueNull=True) CreateDate=Models. Datetimefield (' Create Time ', Auto_now_add=True) lastmdfdate=Models. Datetimefield (' Last modified time ', blank=TrueNull=True)def __str__( Self):return Self. title+' Author: '+ Self. author.username
Here is the main explanation for models. ForeignKey () parameter, the first parameter is the ' one ' corresponding category in the ' A-to-many ' relationship, Blogtag the code snippet of the model.
tagtype=models.ForeignKey(TagType,on_delete=models.SET_NULL,blank=True,null=True)
means that the Tagtype property of the Blogtag instance can only point to an instance of a Tagtype class. In the case where the Tagtype attribute of Blogtag points to the same Tagtype class instance, We can create multiple instances of the Blogtype class. This enables a tagtype to correspond to multiple blogtag relationships.
The code snippet in the Blog model:
tag=models.ManyToManyField(BlogTag)
Refers to the blog's Tag property points to multiple instances of Blogtag, when creating a blog instance (Manytomanyfield's point is empty by default).
It is important to note that every time you modify or add a new model, you need to python manage.py makemigrations
python manage.py migrate
synchronize the changes or new model to the database!
2 testcase Unit Test
After the completion of the database synchronization, is to do unit testing, do not feel cumbersome, must develop such a habit!! Edit the MyBlog file directory under the tests.py, add to the ' Tagtype ', ' blogtag ', ' Blog ' three model test class (because the three categories are connected, I have written about their test in a test Class):
classBlogtestcase (TestCase):defCreate_test ( Self): test_user,created=BlogUser.objects.update_or_create (username=' Test_blog_user ', email=' [email protected] ', password=' Test ', gender=' M ')Print(Test_user) test_type1,created=TagType.objects.update_or_create (TypeName=' Math ')#添加数学这个大类test_type2,created=TagType.objects.update_or_create (TypeName=' programming ')#添加编程大类 Print(Tagtype.objects. All())#TagType. Objects.all () means taking an instance of all current Tagtypemat_test_tag1,created=BlogTag.objects.update_or_create (Tagtype=Test_type1,tagename=' Advanced mathematics ') mat_test_tag2,created=BlogTag.objects.update_or_create (Tagtype=Test_type1,tagename=' linear algebra ') prm_test_tag1,created=BlogTag.objects.update_or_create (Tagtype=Test_type2,tagename=' python ') prm_test_tag2,created=BlogTag.objects.update_or_create (Tagtype=Test_type2,tagename=' Django ')Print(Blogtag.objects. All())Print(Blogtag.objects.Filter(Tagtype=TEST_TYPE1))#取高数大类下的所有标签 Print(Blogtag.objects.Filter(Tagtype=TEST_TYPE2))#取编程大类下的所有标签test_blog,created=Blog.objects.update_or_create (title=' Test blog ', author=Test_user)#创建测试Blog实例 Print(Test_blog)Print(Test_blog.tag. All())#列出test_blog实例的所有标签Test_blog.tag.add (PRM_TEST_TAG1,PRM_TEST_TAG2)#为test_blog添加标签 Print(Test_blog.tag. All())
./manage.py test myBlog.tests.BlogTestCase.create_test
Results:.
3 Modelform
The previous blog post said a custom form, and here's another category: Modelform.
Modelform is a form flexibility that is not as high as a custom form. Modelfrom is also a subclass of the form. Edit
MyBlog file directory forms.py
,
To import the model first:
fromimport Blog, BlogTag, TagType
Then add the following code to define three form for ' Tagtype ', ' blogtag ', ' Blog ' three model:
class TagTypeForm(forms.ModelForm): class Meta: model=TagType#指向TagType这个model fields=[‘typename‘]#前台的input框输入的是内容对应typename字段class BlogTagForm(forms.ModelForm): class Meta: model=BlogTag fields=[‘tagtype‘,‘tagename‘]class BlogForm(forms.ModelForm): class Meta: model=Blog fields=[‘title‘,‘tag‘,‘content‘,‘author‘]
4 Template Templates Page
Add a new blog.html file to the template file directory to display the form:
<! DOCTYPEHtml>lang="en"dir="LTR">{% load static%} <metacharset="Utf-8"> <title>Edit Label</title> <scripttype="Text/javascript", SRC="{% static ' js/jquery-3.2.1.min.js '%}"> </script> <scripttype="Text/javascript"> </script> <body> <divclass=""> <formclass="Tag_type_form"action=""method="POST">{% Csrf_token%} {{Type_form}}<buttontype="Submit"name="SUB_BTN">Add Category</button> </form> </div> <divclass=""> <formclass="Blog_tag_form"action="{% url ' btag '%}"method="POST"><!--action= "{% url ' btag '%}" is to submit the request to the urls.py file urlpatterns the list name= ' btag ' corresponding URL--{% Csrf_token%} {{Tag_form}}<buttontype="Submit"name="TAG_BTN"id=' tag_btn '>Add tags</button> </form> </div> <divclass=""> Existing blogs:{% for blog in blogs%} {{Blog.title}}<br>{% ENDFOR%}</div> <divclass=""> <formclass=""action="{% url ' blogedit '%}"method="POST">{% Csrf_token%} {{Blog_form}}<buttontype="Submit"name="button">Edit Complete</button> </form> </div> </body>
5 views.py Defining a view class
First, import the model and form:
python from myBlog.forms import RegisterForm, TagTypeForm,BlogTagForm,BlogForm#导入我们在forms.py自定义的form表单 from myBlog.models import BlogUser, TagType, BlogTag, Blog
We'll use redirects later, and here we'll start with the import:
fromimport #导入HttpResponse对象fromimport reverse
Then start defining the View class:
classTagview (View):" handling requests for large categories " defGet Self, request): Template_name=' blog.html 'Type_form=Tagtypeform () Tag_form=Blogtagform () Blog_form=Blogform () blog_tags=Blogtag.objects. All() Blogs=Blog.objects. All() form_dict={' Type_form ': Type_form,' Tag_form ': Tag_form,' Blog_form ': Blog_form,' Blogs ': Blogs,}returnRender (Request,template_name,form_dict)defPost Self, request): Template_name=' blog.html 'Type_form=Tagtypeform () Tag_form=Blogtagform () Blog_form=Blogform () Form=Tagtypeform (Request. POST)ifForm.is_valid (): Form.save ()returnHttpresponseredirect (Reverse (' tag '))#重定向到urls The URL of name= ' tag ' in the. py fileclassBlogtagview (View):defGet Self, request):Pass defPost Self, request): Form=Blogtagform (Request. POST)ifForm.is_valid (): Form.save ()returnHttpresponseredirect (Reverse (' tag '))classBlogview (View):"" " docstring for Blogview. " "" defGet Self, request):Pass defPost Self, request): Form=Blogform (Request. POST)ifForm.is_valid (): Form.save ()returnHttpresponseredirect (Reverse (' tag '))
6 urls.py Configuration
Modify the urls.py file in the MyBlog file directory to import the view class that you just defined.
fromimport RegisterView, TagView, BlogView, BlogTagView
Configure the route, and at the end of the path (), add a keyword parameter name and assign the value:
urlpatterns=[path(‘registe‘,RegisterView.as_view(),name=‘registe‘),path(‘tag‘,TagView.as_view(),name=‘tag‘),#reserve(‘tag‘)和页面中{% url ‘tag‘%}与这个url对应path(‘btag‘,BlogTagView.as_view(),name=‘btag‘),path(‘blogedit‘,BlogView.as_view(),name=‘blogedit‘),]
It's time to test the results, python manage.py runserver 8080
start the service, and then visit 127.0.0.1:8080/blog/tag
, there's a humble page, and we can add some tags and it's almost like this:
.
Is this page too shabby? I also think it's ugly. The next blog post is about static files, and we can make this page a bit more uncluttered with static files!
Django Basics Four < two > (Onetomany and Manytomany,modelform)