天天看点

自学Django之路---Day2.连接mysql数据库、级联

昨天连接的数据库是sqlite3,今天使用mysql。

pycharm shift + f6 重命名

netstat -ano 查看端口

tasklist|findstr “3436” 查看是谁在用这个端口

taskkill /pid 4636 /f 终止对应端口的进程

装mysql真的好麻烦啊…

重启mysql:net start mysql

遇见的问题:

  1. mysql启动失败:mysql服务无法启动 服务没有报告任何错误

    解决方案:https://blog.csdn.net/shinny195/article/details/82319218

  2. Can’t connect to MySql server on ‘localhost’(10061)

    解决方案:https://blog.csdn.net/yyx3214/article/details/97097696

  3. 修改密码时,我刚开始用的:alter user ‘root’@‘localhost’ identified by ‘123’; 但是报错:
    ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'password('123')' at line 1
               
    解决方案:使用 mysql> set password for [email protected] = password(‘123’);
  4. 使用pycharm导入mysql数据库时,出现:Server returns invalid timezone

    解决方案:https://blog.csdn.net/ITMan2017/article/details/100601438

首先在settings.py中找到:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
           

将其改成:

DATABASES = {
    'default': {
        # 'ENGINE': 'django.db.backends.sqlite3',
        # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'GP1HelloDjango',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
           

然后准备mysql:

  • mysql -uroot -p 回车,输入密码
  • create database GP1HelloDjango charset=utf8; 创建在settings中写的数据库
  • 在pycharm中可以访问mysql数据库了
    1. 在数据库那里点加号,data source -> mysql -> 写上你的数据库名称即可
  • 现在mysql数据库表中没有数据,因此要迁移,但上篇说过,迁移文件生成之后只需要执行python manager.py migrate就行了

好吧,做到这里时出现了问题,虚拟环境中的pip变成了全局的,python也是,除非在命令前加上虚拟环境的目录否则都是对全局进行操作,原因我查了很多但都没解决问题。

正打算要重做系统…忽然发现可以用anaconda自带的虚拟环境(conda create 名字),创建完之后再安装库(Django、python…),然后在pycharm换一下解释器就又可以了

执行python manager.py migrate后又报错:

大致是:
ModuleNotFoundError: No module named 'MySQLdb'
...
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
Did you install mysqlclient?
           

应该是连接mysql的驱动没有安装,大致有以下几种:

  • mysqlclient
    1. 兼容python2、3
    2. 对mysql安装有要求,必须在指定位置存在配置文件
  • python-mysql
    1. 对python2支持,不支持python3
  • pymysql
    1. 兼容python2、3
    2. 可以伪装成上述数据库

因此用第三个,pip install pymysql(慢的话用源:pip install pymysql -i https://pypi.douban.com/simple)

装完了还是不行,因为要让它伪装,在主项目__init__中:

import pymysql
pymysql.install_as_MySQLdb()
           

然后我运行了,还是不行…错误是:

django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3
           

于是我又找资料,有大佬说改一下\Lib\site-packages\django\db\backends\mysql 里面的base.py文件:

改源码:https://blog.csdn.net/weixin_45476498/article/details/100098297

不需要改源码:https://blog.csdn.net/lpw_cn/article/details/103978909

version = Database.version_info
# if version < (1, 3, 13):
#     raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)
把2、3行注释掉
           

又有如下错误:

AttributeError: 'str' object has no attribute 'decode'
           

解决方案:

if query is not None:
        # query = query.decode(errors='replace')
        query = query.encode(errors='replace')
    return query
顺着报错文件点进去,找到query = query.decode(errors=‘replace’)
将decode修改为encode即可
           

终于可以了…

关于模板

昨天用了两种方式来返回消息:

  1. return HttpResponse(’…’)
  2. return render(’…’)

其实第二种方式是简写,具体是这样的:

from django.template import loader
def index(request):
    temp = loader.get_template('html文件')
    res = temp.render()
    return HttpResponse(res)
           

先读文件,然后将模板语言渲染成html,再给HttpResponse,其实如果没有模板语言(for、if)那么使用open打开也是一样的

级联数据

现在有学生和班级,很显然让学生记住班级更容易操作,那么班级的主键就是学生的外键。

另建一个app,如Three,不要忘了settings注册、urls这些准备工作,models

class Grade(models.Model):
    g_name = models.CharField(max_length=32)


class Student(models.Model):
    s_name = models.CharField(max_length=16)
    s_grade = models.ForeignKey(Grade, on_delete=models.CASCADE)
           

由于改变了models,所以要

  • python manage.py makemigrations
  • python manage.py migrate

之后,在grade和student表中添加几条数据,然后写一个根据学生id查班级的方法:

def get_grade(request):
    student = Student.objects.get(pk=1)
    grade = student.s_grade
    return HttpResponse('Grade is %s' % grade.g_name)
           

再根据班级把所有属于该班级的学生找出来:

def get_students(request):
    grade = Grade.objects.get(pk=1)
    students = grade.student_set.all()
    context = {
        'students': students
    }

    return render(request, 'students.html', context=context)