-----------------添加学习用户---------------------
在model中定义方法
(该方法如果想在模板语言中使用,不能传递参数,因为模板语言是没有括号的,可以写self.usercourse_set.all().count()来计算总数)
class Course(models.Model):
。。。
def get_user(self):
return self.usercourse_set.all() # 外键反向查找
课程和用户之间的多对多表
class UserCourse(models.Model):
"""在用户点击了学习之后,则记录为用户学习的课程即该model的用户课程"""
user = models.ForeignKey(UserProfile,verbose_name=u"用户")
course = models.ForeignKey(Course,verbose_name=u"课程")
点击开始学习之后,那么该用户就会收藏该课程,要在前端显示该课程的用户,在views中
learn_stds = Course.objects.get(id=course_id).get_user()[:3]
前端写:
{% for obj in learn_stds %}
<span class="pic"><img width="40" height="40" src="{{ MEDIA_URL }}{{ obj.user.image }}"/></span>
{% endfor %}
-----------------添加学习用户---------------------
外键正向查找
model
class Course(models.Model):
course_org = models.ForeignKey(CourseOrg,verbose_name=u"课程机构",blank=True,null=True)
name = models.CharField(max_length=100,verbose_name=u"课程名")
class Lesson(models.Model):
course = models.ForeignKey(Course,verbose_name=u"课程")
name = models.CharField(max_length=100,verbose_name=u"章节名")
views
>>>Lesson.objects.filter(course__name=u"python进阶教程")
[<Lesson: Lesson object>, <Lesson: Lesson object>, <Lesson: Lesson object>]
外键反向查找
>>>CourseOrg.objects.get(id=2).course_set.all() # course_set中的course是表course的小写,这样就把id=1的全部Course的记录全部查出来
[<Course: python进阶教程>, <Course: java高阶>, <Course: python入门>, <Course: python高阶>, <Course: java入门>, <Course: mysql入门>, <Course: java进阶>]
在下面的正向查询中如果是要用到id,那么单双下划线都可以的Lesson.object.filter(course_id=1) / Lesson.object.filter(course__id=1)
反向查询还有中方法,通过related_name进行查询
class Student(models.Model):
city = models.ForeignKey(City,verbose_name=u'学生所在城市',null=True,blank=True,related_name='inCity')
此时,就可以通过 City.objects.get(id=1).inCity.all() 这是不能通过City.objects.get(id=1).student_set.all()进行查询。
获取Choices中的值
degree = models.CharField(choices=(("gj",u"高级"),("zj",u"中级"),("cj",u"低级")),max_length=2,verbose_name=u"难度")
前端
{{ obj.get_degree_display }}
{{ obj.degree }}
多对多关系异同点:
Business表
首先,有一张记录了所有机器的的主机表。(foreignkey是多对一关系:就是说business中的运维部可以对应多个机器)
class Host(models.Model):
nid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32,db_index=True)
ip = models.GenericIPAddressField(protocol="ipv4",db_index=True)
port = models.IntegerField()
b = models.ForeignKey(to="Business", to_field='id')
在表中添加数据
假如,我们有这样一个需求,公司需要把正在生产app的主机关联上各自的app项目(可能一台机器正在生产一个app项目,也可能多台机器生产一个app项目,也可能一台机器生产多个app项目),这样我们就需要有一张表来对应多对多关系。
创建多对多关系表一般有2种方式:
方法一:自定义关系表
class Application(models.Model):
name = models.CharField(max_length=32)
class HostToApp(models.Model):
hobj = models.ForeignKey(to='Host',to_field='nid')
aobj = models.ForeignKey(to='Application',to_field='id')
通过HostToApp将Application和Host关联起来
但是这样创建有个坏处就是可以重复写。但实际情况是不需要主机1对应app1,主机1对应app1写2次。所以写的时候要注意。好处就是,这样创建你不仅可以关联host的nid,也可以关联hostname,管理程度更大。
nobj = models.ForeignKey(to='Host',to_field='hostname')
方法二:自动创建关系表
class Applicate(models.Model):
name = models.CharField(max_length=32)
r = models.ManyToManyField("Host")
这样创建的时候,会自动生成一张applicate_r的表用于关联,在这张表中无法写1-3,1-3 两次。缺点是表中只能id对应id
通过方式2要操作这样表需要通过这个r接口来操作
obj = Application.objects.get(id=1)
# 第三张表操作
obj.r.add(1)
obj.r.add(2)
obj.r.add(2,3,4) // obj.r.add(*[1,2,3,4]) // obj.r.set([3,5,7])
obj.r.remove(1)
obj.r.remove(2,4) // obj.r.remove(*[1,2,3])
obj.r.clear()
# 所有相关的主机对象“列表” QuerySet
obj = models.Applicate.objects.get(id=2)
obj.r.all() : <QuerySet [<Host: Host object>, <Host: Host object>, <Host: Host object>]>,获取到了host对象,我们就可以取到host的值了