孝感网站开发,电子商务网站建设与管理小论文,网站建设工作自策划实施以来,关键词林俊杰mp3免费下载前面已经学习了在Django里面如何对单表的操作#xff0c;同时也学习了1对多(单个外键)的表的操作。接下来#xff0c;我们看看多对多(多个外键)的关系如何创建和管理。比如说#xff0c;我们有一个主机表#xff0c;也有一个应用程序表#xff0c;一个主机可以对应多个程序…前面已经学习了在Django里面如何对单表的操作同时也学习了1对多(单个外键)的表的操作。接下来我们看看多对多(多个外键)的关系如何创建和管理。比如说我们有一个主机表也有一个应用程序表一个主机可以对应多个程序一个程序也可以对应多个主机这是一个典型的多对多的结构。一般来说我们会在数据库里创建一个中间的表分别和这两个表进行外键关联。例1. 手动的定义一个HostToApp表关联到Host和Application表这样一来如果我希望创建一个新的关联我直接对这个中间的表进行操作即可class Host(models.Model):nid models.AutoField(primary_keyTrue)hostname models.CharField(max_length32,db_indexTrue)ip models.GenericIPAddressField(protocolipv4,db_indexTrue)port models.IntegerField()b models.ForeignKey(toBusiness, to_fieldid)class Application(models.Model):name models.CharField(max_length32)class HostToApp(models.Model):hobj models.ForeignKey(toHost,to_fieldnid)aobj models.ForeignKey(toApplication,to_fieldid)#创建一个新的关联关系HostToApp.objects.create(hobj_id1,aobj_id2)例2. 除了手动创建一个关系表我们还可以让系统自动生成一个class Host(models.Model):nid models.AutoField(primary_keyTrue)hostname models.CharField(max_length32,db_indexTrue)ip models.GenericIPAddressField(protocolipv4,db_indexTrue)port models.IntegerField()b models.ForeignKey(toBusiness, to_fieldid)class Application(models.Model):name models.CharField(max_length32)r models.ManyToManyField(Host)执行manage.py migrate和 manage.py migration 之后查看数据库可以看见自动生成了一个关系表app01_application_r, 里面有3个字段一个id和两个外键这个自动生成的表在Django里面不能直接像单表一样操作因为系统并不知道他的‘存在’因此只能通过间接的操作。间接操作查询//这里首先获取app_id1的对象后面的操作都是基于这个前提来的objmodels.Application.objects.get(id1)obj.nameobj.r.all() //类似单表操作增加obj.r.add(1) //添加app_id1, host_id1的记录obj.r.add(2,3,4) //直接添加多个值obj.r.add(*[1,2,3,4]) // 直接通过列表的格式添加多个值删除,格式和增加一样obj.r.remove(1)obj.r.remove(2,3)obj.r.remove(*[2,3,4])obj.r.clear() //删除所有app_id1的关系修改obj.r.set([2,3,4]) //直接设置app_id1, host_id2,3,4,注意列表前面没有星号例3. 下面看个实例models.pyclass Host(models.Model):nid models.AutoField(primary_keyTrue)hostname models.CharField(max_length32,db_indexTrue)ip models.GenericIPAddressField(protocolipv4,db_indexTrue)port models.IntegerField()b models.ForeignKey(toBusiness, to_fieldid)class Application(models.Model):name models.CharField(max_length32)r models.ManyToManyField(Host)urls.py ( 里面有 views.app和 views.ajax_add_app,对比ajax和普通使用)from django.conf.urls import urlfrom django.contrib import adminfrom app01 import viewsurlpatterns [url(r^admin/, admin.site.urls),url(r^business$, views.business),url(r^host$, views.host),url(r^test_ajax$, views.test_ajax),url(r^app$, views.app),url(r^ajax_add_app$, views.ajax_add_app),views.py 注意获取用户输入的新的App名称和这个App所对应的主机列表分别在不同的表进行创建新数据def app(request):if request.method GET:app_list models.Application.objects.all()host_list models.Host.objects.all()return render(request,app.html,{app_list: app_list,host_list: host_list})elif request.method POST:app_name request.POST.get(app_name)host_list request.POST.getlist(host_list)print(app_name,host_list)#直接obj就是创建的新数据的对象obj models.Application.objects.create(nameapp_name)#间接添加列表前面加*obj.r.add(*host_list)return redirect(/app)def ajax_add_app(request):ret {status:True, error:None, data: None}app_name request.POST.get(app_name)host_list request.POST.getlist(host_list)obj models.Application.objects.create(nameapp_name)obj.r.add(*host_list)return HttpResponse(json.dumps(ret))app.html主要界面是就是显示当前数据和一个模态对话框。点击添加弹出对话框然后输入App和对应的主机名后台获取之后添加返回页面html.host-tag{display: inline-block;padding: 3px;border: 1px solid red;background-color: palevioletred;}.hide{display: none;}.shade{position: fixed;top: 0;right: 0;left: 0;bottom: 0;background: black;opacity: 0.6;z-index: 100;}.add-modal,.edit-modal{position: fixed;height: 300px;width: 400px;top:100px;left: 50%;z-index: 101;border: 1px solid red;background: white;margin-left: -200px;}应用列表应用名称应用主机列表{% for app in app_list %}{{ app.name }}{% for host in app.r.all %} {{ host.hostname }} {% endfor %}编辑{% endfor %}//multiple允许多选发送到后台是一个列表后台通过get_list接收{% for op in host_list %}{{ op.hostname }}{% endfor %}$(function(){//显示对话框$(#add_app).click(function(){$(.shade,.add-modal).removeClass(hide);});//隐藏对话框$(#cancel).click(function(){$(.shade,.add-modal).addClass(hide);});//发送一个Ajax请求序列化的时候可以直接通过form.serialize()dataType指定JSON这样就不需要获取之后再做个JSON.parse(data)如果是单个数据后台可以直接接收如果存在列表数据需要指定tradtional是True$(#add_submit_ajax).click(function(){$.ajax({url: /ajax_add_app,// data: {user: 123,host_list: [1,2,3,4]},data: $(#add_form).serialize(),type: POST,dataType: JSON, // 内部traditional: true,success: function(obj){console.log(obj);},error: function () {}})});})结果如下所示在我们使用模态对话框的时候使用AJAX的好处是可以实现一些验证的功能如果我们不在同一个Url里面使用模态对话框而是新开一个URL来创建数据可以直接用普通的form提交就行了。模态对话框适合小数据的提交而新的Url更适合大量数据的提交(比如新开一个页面写博客)