django(四)---数据库与ORM

来源:互联网 发布:属性数据分析引论 编辑:程序博客网 时间:2024/06/05 09:59
数据库的配置
1    django默认支持sqlite,mysql, oracle,postgresql数据库。
     <1> sqlite
            django默认使用sqlite的数据库,默认自带sqlite的数据库驱动 , 引擎名称:django.db.backends.sqlite3
     <2> mysql
            引擎名称:django.db.backends.mysql
2    mysql驱动程序
   MySQLdb(mysql python)
   mysqlclient
   MySQL
   PyMySQL(纯python的mysql驱动程序)
3     在django的项目中会默认使用sqlite数据库,在settings里有如下设置:
# Database# https://docs.djangoproject.com/en/1.11/ref/settings/#databases# DATABASES = {#     'default': {#         'ENGINE': 'django.db.backends.sqlite3',#         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),#     }# }

如果我们想要更改数据库,需要修改如下:
DATABASES = {    'default': {        'ENGINE': 'django.db.backends.mysql',        'NAME': 's5ORM',    #你的数据库名称        'USER': 'root',   #你的数据库用户名        'PASSWORD': '', #你的数据库密码        'HOST': '', #你的数据库主机,留空默认为localhost        'PORT': '3306', #你的数据库端口    }}

注意

NAME即数据库的名字,在mysql连接前该数据库必须已经创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建USER和PASSWORD分别是数据库的用户名和密码。设置完后,再启动我们的Django项目前,我们需要激活我们的mysql。然后,启动项目,会报错:no module named MySQLdb这是因为django默认你导入的驱动是MySQLdb,可是MySQLdb对于py3有很大问题,所以我们需要的驱动是PyMySQL所以,我们只需要找到项目名文件下的__init__,在里面写入:import pymysqlpymysql.install_as_MySQLdb()问题解决!

=================================================================

概述

1.什么是ORM?

ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法。

2.ORM的优缺点是什么?

优点:摆脱复杂的SQL操作,适应快速开发;让数据结构变得简洁;数据库迁移成本更低(如从mysql->oracle)

缺点:性能较差、不适用于大型应用;复杂的SQL操作还需通过SQL语句实现

-------------------------------------------------------------------------------------------------------------------

建表:

实例:我们来假定下面这些概念,字段和关系

作者模型:一个作者有姓名。

作者详细模型:把作者的详情放到详情表,包含性别,email地址和出生日期,作者详情模型和作者模型之间是一对一的关系(one-to-one)(类似于每个人和他的身份证之间的关系),在大多数情况下我们没有必要将他们拆分成两张表,这里只是引出一对一的概念。

出版商模型:出版商有名称,地址,所在城市,省,国家和网站。

书籍模型:书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many),一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many),也被称作外键。

在models.py中写入:

from django.db import models<br>class Publisher(models.Model):    name = models.CharField(max_length=30, verbose_name="名称")    address = models.CharField("地址", max_length=50)    city = models.CharField('城市',max_length=60)    state_province = models.CharField(max_length=30)    country = models.CharField(max_length=50)    website = models.URLField()     class Meta:        verbose_name = '出版商'        verbose_name_plural = verbose_name     def __str__(self):        return self.name class Author(models.Model):    name = models.CharField(max_length=30)    def __str__(self):        return self.name class AuthorDetail(models.Model):    sex = models.BooleanField(max_length=1, choices=((0, '男'),(1, '女'),))    email = models.EmailField()    address = models.CharField(max_length=50)    birthday = models.DateField()    author = models.OneToOneField(Author) class Book(models.Model):    title = models.CharField(max_length=100)    authors = models.ManyToManyField(Author)    publisher = models.ForeignKey(Publisher)    publication_date = models.DateField()    price=models.DecimalField(max_digits=5,decimal_places=2,default=10)    def __str__(self):        return self.title

分析代码:

       <1>  每个数据模型都是django.db.models.Model的子类,它的父类Model包含了所有必要的和数据库交互的方法。并提供了一个简介漂亮的定义数据库字段的语法。

       <2>  每个模型相当于单个数据库表(多对多关系例外,会多生成一张关系表),每个属性也是这个表中的字段。属性名就是字段名,它的类型(例如CharField)相当于数据库的字段类型(例如varchar)。大家可以留意下其它的类型都和数据库里的什么字段对应。

       <3>  模型之间的三种关系:一对一,一对多,多对多。

             一对一:实质就是在主外键(author_id就是foreign key)的关系基础上,给外键加了一个UNIQUE=True的属性;

             一对多:就是主外键关系;(foreign key)

             多对多:(ManyToManyField) 自动创建第三张表(当然我们也可以自己创建第三张表:两个foreign key)

-------------------------------------------------------------------------------------------------------------------

ORM之增(create,save) 

在views中写入:

from app01.models import *    #create方式一:   Author.objects.create(name='Alvin')    #create方式二:   Author.objects.create(**{"name":"alex"})    #save方式一:     author=Author(name="alvin")                            author.save()    #save方式二:     author=Author()                            author.name="alvin"                            author.save()

重点来了------->那么如何创建存在一对多或多对多关系的一本书的信息呢?(如何处理外键关系的字段如一对多的publisher和多对多的authors)
#一对多(ForeignKey):    #方式一: 由于绑定一对多的字段,比如publish,存到数据库中的字段名叫publish_id,所以我们可以直接给这个    #       字段设定对应值:           Book.objects.create(title='php',                               publisher_id=2,   #这里的2是指为该book对象绑定了Publisher表中id=2的行对象                               publication_date='2017-7-7',                               price=99)    #方式二:    #       <1> 先获取要绑定的Publisher对象:        pub_obj=Publisher(name='河大出版社',address='保定',city='保定',                state_province='河北',country='China',website='http://www.hbu.com')    OR  pub_obj=Publisher.objects.get(id=1)    #       <2>将 publisher_id=2 改为  publisher=pub_obj#多对多(ManyToManyField()):    author1=Author.objects.get(id=1)    author2=Author.objects.filter(name='alvin')[0]    book=Book.objects.get(id=1)    book.authors.add(author1,author2)    #等同于:    book.authors.add(*[author1,author2])    book.authors.remove(*[author1,author2])    #-------------------    book=models.Book.objects.filter(id__gt=1)    authors=models.Author.objects.filter(id=1)[0]    authors.book_set.add(*book)    authors.book_set.remove(*book)    #-------------------    book.authors.add(1)    book.authors.remove(1)    authors.book_set.add(1)    authors.book_set.remove(1)#注意: 如果第三张表是通过models.ManyToManyField()自动创建的,那么绑定关系只有上面一种方式#     如果第三张表是自己创建的:     class Book2Author(models.Model):            author=models.ForeignKey("Author")            Book=  models.ForeignKey("Book")#     那么就还有一种方式:            author_obj=models.Author.objects.filter(id=2)[0]            book_obj  =models.Book.objects.filter(id=3)[0]            s=models.Book2Author.objects.create(author_id=1,Book_id=2)            s.save()            s=models.Book2Author(author=author_obj,Book_id=1)            s.save()

-------------------------------------------------------------------------------------------------------------------

ORM之删(delete)

Book.objects.filter(id=1).delete()(3, {'app01.Book_authors': 2, 'app01.Book': 1})
我们表面上删除了一条信息,实际却删除了三条,因为我们删除的这本书在Book_authors表中有两条相关信息,这种删除方式就是django默认的级联删除。
-------------------------------------------------------------------------------------------------------------------
ORM之改(update和save)

     

注意:

<1> 第二种方式修改不能用get的原因是:update是QuerySet对象的方法,get返回的是一个model对象,它没有update方法,而filter返回的是一个QuerySet对象(filter里面的条件可能有多个条件符合,比如name='alvin',可能有两个name='alvin'的行数据)。

<2>在“插入和更新数据”小节中,我们有提到模型的save()方法,这个方法会更新一行里的所有列。 而某些情况下,我们只需要更新行里的某几列。

#---------------- update方法直接设定对应属性----------------    models.Book.objects.filter(id=3).update(title="PHP")    ##sql:    ##UPDATE "app01_book" SET "title" = 'PHP' WHERE "app01_book"."id" = 3; args=('PHP', 3)#--------------- save方法会将所有属性重新设定一遍,效率低-----------    obj=models.Book.objects.filter(id=3)[0]    obj.title="Python"    obj.save()# SELECT "app01_book"."id", "app01_book"."title", "app01_book"."price", # "app01_book"."color", "app01_book"."page_num", # "app01_book"."publisher_id" FROM "app01_book" WHERE "app01_book"."id" = 3 LIMIT 1; # # UPDATE "app01_book" SET "title" = 'Python', "price" = 3333, "color" = 'red', "page_num" = 556,# "publisher_id" = 1 WHERE "app01_book"."id" = 3;

   此外,update()方法对于任何结果集(QuerySet)均有效,这意味着你可以同时更新多条记录update()方法会返回一个整型数值,表示受影响的记录条数。


注意,这里因为update返回的是一个整形,所以没法用query属性;对于每次创建一个对象,想显示对应的raw sql,需要在settings加上日志记录部分:
LOGGING = {    'version': 1,    'disable_existing_loggers': False,    'handlers': {        'console':{            'level':'DEBUG',            'class':'logging.StreamHandler',        },    },    'loggers': {        'django.db.backends': {            'handlers': ['console'],            'propagate': True,            'level':'DEBUG',        },    }}

=================================================================

ORM之查(filter,value) 

# 查询相关API:#  <1>filter(**kwargs):      它包含了与所给筛选条件相匹配的对象#  <2>all():                 查询所有结果#  <3>get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。#-----------下面的方法都是对查询的结果再进行处理:比如 objects.filter.values()--------#  <4>values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列                                     #  <5>exclude(**kwargs):     它包含了与所给筛选条件不匹配的对象#  <6>order_by(*field):      对查询结果排序#  <7>reverse():             对查询结果反向排序#  <8>distinct():            从返回结果中剔除重复纪录#  <9>values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列#  <10>count():              返回数据库中匹配查询(QuerySet)的对象数量。#  <11>first():               返回第一条记录#  <12>last():                返回最后一条记录#  <13>exists():             如果QuerySet包含数据,就返回True,否则返回False

---------------了不起的双下划线(__)之单表条件查询----------------#    models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值##    models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据#    models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in##    models.Tb1.objects.filter(name__contains="ven")#    models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感##    models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and##    startswith,istartswith, endswith, iendswith,

-------------------------------------------------------------------------------------------------------------------

QuerySet与惰性机制

所谓惰性机制:Publisher.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用QuerySet的时候才执行。

QuerySet特点:

       <1>  可迭代的

       <2>  可切片

#objs=models.Book.objects.all()#[obj1,obj2,ob3...]    #QuerySet:   可迭代    # for obj in objs:#每一obj就是一个行对象    #     print("obj:",obj)    # QuerySet:  可切片    # print(objs[1])    # print(objs[1:4])    # print(objs[::-1])

QuerySet的高效使用:

<1>Django的queryset是惰性的     Django的queryset对应于数据库的若干记录(row),通过可选的查询来过滤。例如,下面的代码会得     到数据库中名字为‘Dave’的所有的人:person_set = Person.objects.filter(first_name="Dave")     上面的代码并没有运行任何的数据库查询。你可以使用person_set,给它加上一些过滤条件,或者将它传给某个函数,     这些操作都不会发送给数据库。这是对的,因为数据库查询是显著影响web应用性能的因素之一。<2>要真正从数据库获得数据,你可以遍历queryset或者使用if queryset,总之你用到数据时就会执行sql.   为了验证这些,需要在settings里加入 LOGGING(验证方式)        obj=models.Book.objects.filter(id=3)        # for i in obj:        #     print(i)        # if obj:        #     print("ok")<3>queryset是具有cache的     当你遍历queryset时,所有匹配的记录会从数据库获取,然后转换成Django的model。这被称为执行    (evaluation).这些model会保存在queryset内置的cache中,这样如果你再次遍历这个queryset,     你不需要重复运行通用的查询。        obj=models.Book.objects.filter(id=3)        # for i in obj:        #     print(i)                          ## models.Book.objects.filter(id=3).update(title="GO")                          ## obj_new=models.Book.objects.filter(id=3)        # for i in obj:        #     print(i)   #LOGGING只会打印一次<4>     简单的使用if语句进行判断也会完全执行整个queryset并且把数据放入cache,虽然你并不需要这些     数据!为了避免这个,可以用exists()方法来检查是否有数据:            obj = Book.objects.filter(id=4)            #  exists()的检查可以避免数据放入queryset的cache。            if obj.exists():                print("hello world!")<5>当queryset非常巨大时,cache会成为问题     处理成千上万的记录时,将它们一次装入内存是很浪费的。更糟糕的是,巨大的queryset可能会锁住系统     进程,让你的程序濒临崩溃。要避免在遍历数据的同时产生queryset cache,可以使用iterator()方法     来获取数据,处理完数据就将其丢弃。        objs = Book.objects.all().iterator()        # iterator()可以一次只从数据库获取少量数据,这样可以节省内存        for obj in objs:            print(obj.name)        #BUT,再次遍历没有打印,因为迭代器已经在上一次遍历(next)到最后一次了,没得遍历了        for obj in objs:            print(obj.name)     #当然,使用iterator()方法来防止生成cache,意味着遍历同一个queryset时会重复执行查询。所以使     #用iterator()的时候要当心,确保你的代码在操作一个大的queryset时没有重复执行查询总结:    queryset的cache是用于减少程序对数据库的查询,在通常的使用下会保证只有在需要的时候才会查询数据库。使用exists()和iterator()方法可以优化程序对内存的使用。不过,由于它们并不会生成queryset cache,可能会造成额外的数据库查询。
-------------------------------------------------------------------------------------------------------------------
对象查询,单表条件查询,多表条件关联查询


#--------------------对象形式的查找--------------------------    # 正向查找    ret1=models.Book.objects.first()    print(ret1.title)    print(ret1.price)    print(ret1.publisher)    print(ret1.publisher.name)  #因为一对多的关系所以ret1.publisher是一个对象,而不是一个queryset集合    # 反向查找    ret2=models.Publish.objects.last()    print(ret2.name)    print(ret2.city)    #如何拿到与它绑定的Book对象呢?    print(ret2.book_set.all()) #ret2.book_set是一个queryset集合#---------------了不起的双下划线(__)之单表条件查询----------------#    models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值##    models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据#    models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in##    models.Tb1.objects.filter(name__contains="ven")#    models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感##    models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and##    startswith,istartswith, endswith, iendswith,#----------------了不起的双下划线(__)之多表条件关联查询---------------# 正向查找(条件)#     ret3=models.Book.objects.filter(title='Python').values('id')#     print(ret3)#[{'id': 1}]      #正向查找(条件)之一对多      ret4=models.Book.objects.filter(title='Python').values('publisher__city')      print(ret4)  #[{'publisher__city': '北京'}]      #正向查找(条件)之多对多      ret5=models.Book.objects.filter(title='Python').values('author__name')      print(ret5)      ret6=models.Book.objects.filter(author__name="alex").values('title')      print(ret6)      #注意      #正向查找的publisher__city或者author__name中的publisher,author是book表中绑定的字段      #一对多和多对多在这里用法没区别# 反向查找(条件)    #反向查找之一对多:    ret8=models.Publisher.objects.filter(book__title='Python').values('name')    print(ret8)#[{'name': '人大出版社'}]  注意,book__title中的book就是Publisher的关联表名    ret9=models.Publisher.objects.filter(book__title='Python').values('book__authors')    print(ret9)#[{'book__authors': 1}, {'book__authors': 2}]    #反向查找之多对多:    ret10=models.Author.objects.filter(book__title='Python').values('name')    print(ret10)#[{'name': 'alex'}, {'name': 'alvin'}]    #注意    #正向查找的book__title中的book是表名Book    #一对多和多对多在这里用法没区别
注意:条件查询即与对象查询对应,是指在filter,values等方法中的通过__来明确查询条件。
--------------------------------------------------------------------------------------------------------------------

聚合查询和分组查询

<1> aggregate(*args,**kwargs):

通过对QuerySet进行计算,返回一个聚合值的字典。aggregate()中每一个参数都指定一个包含在字典中的返回值。即在查询集上生成聚合。

from django.db.models import Avg,Min,Sum,Max从整个查询集生成统计值。比如,你想要计算所有在售书的平均价钱。Django的查询语法提供了一种方式描述所有图书的集合。>>> Book.objects.all().aggregate(Avg('price')){'price__avg': 34.35}aggregate()子句的参数描述了我们想要计算的聚合值,在这个例子中,是Book模型中price字段的平均值aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它:>>> Book.objects.aggregate(average_price=Avg('price')){'average_price': 34.35}如果你也想知道所有图书价格的最大值和最小值,可以这样查询:>>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price')){'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}

<2> annotate(*args,**kwargs):

可以通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值(也可以是平均值或总和),即为查询集的每一项生成聚合。

ret1=models.Book.objects.values('authors__name').annotate(Sum('price'))print(ret1)#求出每个作者出的书单价的和
查询各个作者出的书的总价格,这里就涉及到分组了,分组条件是authors__name

 查询各个出版社最贵的书价是多少

ret2=models.Book.objects.values('publish__name').annotate(Max('price'))print(ret2)

category_list=models.Article.objects.filter(blog=blog_obj).values_list('category__title').annotate(Count('nid'))
tag_list=models.Article.objects.filter(blog=blog_obj).values_list('tags__title').annotate(Count('nid'))


-------------------------------------------------------------------------------------------------------------------


F查询和Q查询

仅仅靠单一的关键字参数查询已经很难满足查询要求。此时Django为我们提供了F和Q查询:

# F 使用查询条件的值,专门取对象中某列值的操作    # from django.db.models import F    # models.Tb1.objects.update(num=F('num')+1)# Q 构建搜索条件    from django.db.models import Q    #1 Q对象(django.db.models.Q)可以对关键字参数进行封装,从而更好地应用多个查询    q1=models.Book.objects.filter(Q(title__startswith='P')).all()    print(q1)#[<Book: Python>, <Book: Perl>]    # 2、可以组合使用&,|操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象。    Q(title__startswith='P') | Q(title__startswith='J')    # 3、Q对象可以用~操作符放在前面表示否定,也可允许否定与不否定形式的组合    Q(title__startswith='P') | ~Q(pub_date__year=2005)    # 4、应用范围:    # Each lookup function that takes keyword-arguments (e.g. filter(),    #  exclude(), get()) can also be passed one or more Q objects as    # positional (not-named) arguments. If you provide multiple Q object    # arguments to a lookup function, the arguments will be “AND”ed    # together. For example:    Book.objects.get(        Q(title__startswith='P'),        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))    )    #sql:    # SELECT * from polls WHERE question LIKE 'P%'    #     AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')    # import datetime    # e=datetime.date(2005,5,6)  #2005-05-06    # 5、Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面。    # 正确:    Book.objects.get(        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),        title__startswith='P')    # 错误:    Book.objects.get(        question__startswith='P',        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

=================================================================


admin的配置

admin是django强大功能之一,它能共从数据库中读取数据,呈现在页面中,进行管理。默认情况下,它的功能已经非常强大,如果你不需要复杂的功能,它已经够用,但是有时候,一些特殊的功能还需要定制,比如搜索功能,下面这一系列文章就逐步深入介绍如何定制适合自己的admin应用。

如果你觉得英文界面不好用,可以在setting.py 文件中修改以下选项

LANGUAGE_CODE = 'en-us'  #LANGUAGE_CODE = 'zh-hans'

一  认识ModelAdmin

   管理界面的定制类,如需扩展特定的model界面需从该类继承。

二 注册medel类到admin的两种方式:

<1>   使用register的方法

admin.site.register(Book,MyAdmin)

<2>   使用register的装饰器

@admin.register(Book)

三 掌握一些常用的设置技巧

  •     list_display:     指定要显示的字段
  •     search_fields:  指定搜索的字段
  •     list_filter:        指定列表过滤器
  •     ordering:       指定排序字段

 

复制代码
from django.contrib import adminfrom app01.models import *# Register your models here.# @admin.register(Book)#----->单给某个表加一个定制class MyAdmin(admin.ModelAdmin):    list_display = ("title","price","publisher")    search_fields = ("title","publisher")    list_filter = ("publisher",)    ordering = ("price",)    fieldsets =[        (None,               {'fields': ['title']}),        ('price information', {'fields': ['price',"publisher"], 'classes': ['collapse']}),    ]admin.site.register(Book,MyAdmin)admin.site.register(Publish)admin.site.register(Author)




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 主播工资不发怎么办 主播工资被欠怎么办 直播平台不发工资坑主播怎么办 主播公司不发工资怎么办 梦幻月卡用完了怎么办 网易星球实名认证通过不了怎么办 认证过荔枝主播怎么办 苹果手机相机不对焦怎么办 苹果手机摄像头不能对焦了怎么办 闪电邮里面邮件太多怎么办 苹果手机和助理打不开怎么办 苹果我的世界打不开怎么办 ps试用7天到期了怎么办 皮肤锁不住水份怎么办 硫酸弄到皮肤上怎么办 直播时图像反看怎么办 快手直播权限被收回怎么办 快手直播权限被收回了怎么办 腾讯手游助手玩游戏卡怎么办 电脑直播视频打不开了怎么办 平板进水开不了机怎么办 苹果平板进水开不了机怎么办 苹果平板电脑进水了怎么办 电脑换主机以前的文件怎么办 货车卖了没过户怎么办 微交易出金不了怎么办 直播时出现央视影音客户端怎么办 qq账号暂时无法登录怎么办 饿了吃东西胃疼怎么办 早上不吃饭胃疼怎么办 孕晚期胃疼呕吐怎么办 胃疼了一晚上怎么办 微信视频图像倒立怎么办 ps链接图层锁定怎么办 慕课过时间了怎么办 异地恋又要考研怎么办 阴阳师手机绑定上限了怎么办 高考口令卡丢了怎么办 网易将军令换手机了怎么办 须弥bb有弱点土怎么办 战网密码忘记了怎么办