Django 开发内容管理系统_自强学堂

用Django开发一个简易的内容管理系统,比如显示新闻的列表,点击进去可以看内容详情等,新闻发布网站。

1.环境搭建
开发会用 virtualenv 来管理多个开发环境,virtualenvwrapper 使得virtualenv变得更好用

E:\ScienceSoft\Python\Django>mkvirtualenv ContentManagePro
Using base prefix 'c:\\users\\administrator\\appdata\\local\\programs\\python\\p
ython35'
New python executable in C:\Users\Administrator\Envs\ContentManagePro\Scripts\py
thon.exe
Installing setuptools, pip, wheel...done.

(ContentManagePro) E:\ScienceSoft\Python\Django>

二,安装软件,开发 minicms 项目
2.1 创建一个开发环境 minicms

windows

mkvirtualenv minicms


image.png
(ContentManagePro) E:\ScienceSoft\Python\Django>mkvirtualenv minicms
Using base prefix 'c:\\users\\administrator\\appdata\\local\\programs\\python\\p
ython35'
New python executable in C:\Users\Administrator\Envs\minicms\Scripts\python.exe
Installing setuptools, pip, wheel...done.

路径在C:\Users\Administrator\Envs\minicms

image.png

补充:正确的虚拟环境创建和激活方式如下:

# 进入python的安装路径中python文件加下的scripts
# http://www.cnblogs.com/ttrrpp/p/6690253.html
C:\Users\Administrator\AppData\Local\Programs\Python\Python35\Scripts>activate.b
at
'activate.bat' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

C:\Users\Administrator\AppData\Local\Programs\Python\Python35\Scripts>virtualenv env #这一步很重要
Using base prefix 'c:\\users\\administrator\\appdata\\local\\programs\\python\\p
ython35'
New python executable in C:\Users\Administrator\AppData\Local\Programs\Python\Py
thon35\Scripts\env\Scripts\python.exe
Installing setuptools, pip, wheel...done.

C:\Users\Administrator\AppData\Local\Programs\Python\Python35\Scripts>cd C:\Users\Administrator\AppData\Local\Programs\Python\Python35\Scripts\env\Scripts

C:\Users\Administrator\AppData\Local\Programs\Python\Python35\Scripts\env\Script
s>activate.bat

(env) C:\Users\Administrator\AppData\Local\Programs\Python\Python35\Scripts\env\
Scripts>
4、像平常一样安装包,比如:

pip install requests

(env) C:\Users\Administrator\AppData\Local\Programs\Python\Python35\Scripts\env
Scripts>pip install requests
安装成功
也可以在其他盘创建虚拟环境:
(minicms) E:\ScienceSoft\Python>virtualenv env
Using base prefix 'c:\users\administrator\appdata\local\programs\python\p
ython35'
New python executable in E:\ScienceSoft\Python\env\Scripts\python.exe
Installing setuptools, pip, wheel...done.

(minicms) E:\ScienceSoft\Python>cd E:\ScienceSoft\Python\env\Scripts

(minicms) E:\ScienceSoft\Python\env\Scripts>activate.bat

(env) E:\ScienceSoft\Python\env\Scripts>


5、如果你在虚拟环境中暂时完成了工作,则可以停用它:

deactivate

2.2 安装 Django:我已经安装过
2.3 创建项目 minicms 和 应用 news


E:\ScienceSoft\Python\Django>pip install virtualenv virtualenvwrapper
Collecting virtualenv
  Downloading virtualenv-15.1.0-py2.py3-none-any.whl (1.8MB)
    34% |███████████▏                    | 634kB 465kB/s eta 0:00:03
    35% |███████████▍                    | 645kB 550kB/s eta 0:00:03
    35% |███████████▌                    | 655kB 461kB/s eta 0:00:03
    36% |███████████▊                    | 665kB 457kB/s eta 0:00:03
    37% |███████████▉                    | 675kB 568kB/s eta 0:00:03
    37% |████████████                    | 686kB 433kB/s eta 0:00:03
    38% |████████████▎                   | 696kB 432kB/s eta 0:00:0
    38% |████████████▍                   | 706kB 628kB/s eta 0:00:0
    39% |████████████▋                   | 716kB 624kB/s eta 0:00:0
    39% |████████████▉                   | 727kB 485kB/s eta 0:00:0
    40% |█████████████                   | 737kB 441kB/s eta 0:00:0
    41% |█████████████▏                  | 747kB 492kB/s eta 0:00:
    41% |█████████████▎                  | 757kB 419kB/s eta 0:00:
    42% |█████████████▌                  | 768kB 412kB/s eta 0:00:
    42% |█████████████▊                  | 778kB 433kB/s eta 0:00:
    43% |█████████████▉                  | 788kB 565kB/s eta 0:00:
    43% |██████████████                  | 798kB 562kB/s eta 0:00:
    44% |██████████████▏                 | 808kB 525kB/s eta 0:00
    44% |██████████████▍                 | 819kB 465kB/s eta 0:00
    45% |██████████████▋                 | 829kB 598kB/s eta 0:00
    46% |██████████████▊                 | 839kB 581kB/s eta 0:00
    46% |███████████████                 | 849kB 511kB/s eta 0:00
    47% |███████████████▏                | 860kB 787kB/s eta 0:0
    47% |███████████████▎                | 870kB 530kB/s eta 0:0
    48% |███████████████▌                | 880kB 527kB/s eta 0:0
    48% |███████████████▋                | 890kB 247kB/s eta 0:0
    49% |███████████████▉                | 901kB 247kB/s eta 0:0
    50% |████████████████                | 911kB 254kB/s eta 0:0
    50% |████████████████▏               | 921kB 263kB/s eta 0:
    51% |████████████████▍               | 931kB 193kB/s eta 0:
    51% |████████████████▋               | 942kB 201kB/s eta 0:
    52% |████████████████▊               | 952kB 211kB/s eta 0:
    52% |█████████████████               | 962kB 208kB/s eta 0:
    53% |█████████████████               | 972kB 240kB/s eta 0:
    53% |█████████████████▎              | 983kB 242kB/s eta 0
    54% |█████████████████▌              | 993kB 501kB/s eta 0
    55% |█████████████████▋              | 1.0MB 509kB/s eta 0
    55% |█████████████████▉              | 1.0MB 517kB/s eta 0
    56% |██████████████████              | 1.0MB 547kB/s eta 0
    56% |██████████████████▏             | 1.0MB 2.2MB/s eta
    57% |██████████████████▍             | 1.0MB 2.4MB/s eta
    57% |██████████████████▌             | 1.1MB 2.1MB/s eta
    58% |██████████████████▊             | 1.1MB 2.5MB/s eta
    59% |███████████████████             | 1.1MB 2.8MB/s eta
    59% |███████████████████             | 1.1MB 2.8MB/s eta
    60% |███████████████████▎            | 1.1MB 652kB/s eta
    60% |███████████████████▍            | 1.1MB 643kB/s eta
    61% |███████████████████▋            | 1.1MB 562kB/s eta
    61% |███████████████████▉            | 1.1MB 565kB/s eta
    62% |████████████████████            | 1.1MB 476kB/s eta
    62% |████████████████████▏           | 1.1MB 404kB/s et
    63% |████████████████████▍           | 1.2MB 417kB/s et
    64% |████████████████████▌           | 1.2MB 350kB/s et
    64% |████████████████████▊           | 1.2MB 324kB/s et
    65% |████████████████████▉           | 1.2MB 323kB/s et
    65% |█████████████████████           | 1.2MB 439kB/s et
    66% |█████████████████████▎          | 1.2MB 439kB/s e
    66% |█████████████████████▍          | 1.2MB 334kB/s e
    67% |█████████████████████▋          | 1.2MB 332kB/s e
    68% |█████████████████████▊          | 1.2MB 368kB/s e
    68% |██████████████████████          | 1.2MB 421kB/s e
    69% |██████████████████████▏         | 1.3MB 411kB/s
    69% |██████████████████████▎         | 1.3MB 504kB/s
    70% |██████████████████████▌         | 1.3MB 433kB/s
    70% |██████████████████████▊         | 1.3MB 433kB/s
    71% |██████████████████████▉         | 1.3MB 439kB/s
    71% |███████████████████████         | 1.3MB 309kB/s
    72% |███████████████████████▏        | 1.3MB 435kB/s
    73% |███████████████████████▍        | 1.3MB 433kB/s
    73% |███████████████████████▋        | 1.3MB 407kB/s
    74% |███████████████████████▊        | 1.4MB 407kB/s
    74% |████████████████████████        | 1.4MB 379kB/s
    75% |████████████████████████▏       | 1.4MB 377kB/
    75% |████████████████████████▎       | 1.4MB 424kB/
    76% |████████████████████████▌       | 1.4MB 343kB/
    77% |████████████████████████▋       | 1.4MB 383kB/
    77% |████████████████████████▉       | 1.4MB 489kB/
    78% |█████████████████████████       | 1.4MB 455kB/
    78% |█████████████████████████▏      | 1.4MB 461kB
    79% |█████████████████████████▍      | 1.4MB 447kB
    79% |█████████████████████████▋      | 1.5MB 451kB
    80% |█████████████████████████▊      | 1.5MB 395kB
    80% |██████████████████████████      | 1.5MB 393kB
    81% |██████████████████████████      | 1.5MB 428kB
    82% |██████████████████████████▎     | 1.5MB 525k
    82% |██████████████████████████▌     | 1.5MB 439k
    83% |██████████████████████████▋     | 1.5MB 533k
    83% |██████████████████████████▉     | 1.5MB 525k
    84% |███████████████████████████     | 1.5MB 525k
    84% |███████████████████████████▏    | 1.5MB 514
    85% |███████████████████████████▍    | 1.6MB 414
    86% |███████████████████████████▌    | 1.6MB 538
    86% |███████████████████████████▊    | 1.6MB 497
    87% |████████████████████████████    | 1.6MB 451
    87% |████████████████████████████    | 1.6MB 465
    88% |████████████████████████████▎   | 1.6MB 53
    88% |████████████████████████████▍   | 1.6MB 52
    89% |████████████████████████████▋   | 1.6MB 46
    89% |████████████████████████████▉   | 1.6MB 46
    90% |█████████████████████████████   | 1.6MB 53
    91% |█████████████████████████████▏  | 1.7MB 5
    91% |█████████████████████████████▍  | 1.7MB 3
    92% |█████████████████████████████▌  | 1.7MB 3
    92% |█████████████████████████████▊  | 1.7MB 4
    93% |█████████████████████████████▉  | 1.7MB 4
    93% |██████████████████████████████  | 1.7MB 4
    94% |██████████████████████████████▎ | 1.7MB
    95% |██████████████████████████████▍ | 1.7MB
    95% |██████████████████████████████▋ | 1.7MB
    96% |██████████████████████████████▊ | 1.8MB
    96% |███████████████████████████████ | 1.8MB
    97% |███████████████████████████████▏| 1.8MB
    97% |███████████████████████████████▎| 1.8MB
    98% |███████████████████████████████▌| 1.8MB
    98% |███████████████████████████████▊| 1.8MB
    99% |███████████████████████████████▉| 1.8MB
    100% |████████████████████████████████| 1.8M
B 171kB/s
Collecting virtualenvwrapper
  Downloading virtualenvwrapper-4.7.2.tar.gz (90kB)
    45% |██████████████▌                 | 40kB 568kB/s eta 0:00:
    56% |██████████████████              | 51kB 506kB/s eta 0:
    67% |█████████████████████▊          | 61kB 596kB/s et
    79% |█████████████████████████▎      | 71kB 530kB/
    90% |█████████████████████████████   | 81kB 561
    100% |████████████████████████████████| 92kB
 529kB/s
Collecting virtualenv-clone (from virtualenvwrapper)
  Downloading virtualenv-clone-0.2.6.tar.gz
Collecting stevedore (from virtualenvwrapper)
  Downloading stevedore-1.25.0-py2.py3-none-any.whl
Requirement already satisfied: six>=1.9.0 in c:\users\administrator\appdata\loca
l\programs\python\python35\lib\site-packages (from stevedore->virtualenvwrapper)

Collecting pbr!=2.1.0,>=2.0.0 (from stevedore->virtualenvwrapper)
  Downloading pbr-3.1.1-py2.py3-none-any.whl (99kB)
    41% |█████████████▏                  | 40kB 538kB/s eta 0:00:0
    51% |████████████████▍               | 51kB 487kB/s eta 0:0
    61% |███████████████████▊            | 61kB 568kB/s eta
    71% |███████████████████████         | 71kB 511kB/s e
    82% |██████████████████████████▎     | 81kB 484kB
    92% |█████████████████████████████▋  | 92kB 53
    100% |████████████████████████████████| 102k
B 471kB/s
Installing collected packages: virtualenv, virtualenv-clone, pbr, stevedore, vir
tualenvwrapper
  Running setup.py install for virtualenv-clone ... done
  Running setup.py install for virtualenvwrapper ... done
Successfully installed pbr-3.1.1 stevedore-1.25.0 virtualenv-15.1.0 virtualenv-c
lone-0.2.6 virtualenvwrapper-4.7.2

E:\ScienceSoft\Python\Django>pip install virtualenvwrapper-win
Collecting virtualenvwrapper-win
  Downloading virtualenvwrapper-win-1.2.1.zip
Requirement already satisfied: virtualenv in c:\users\administrator\appdata\loca
l\programs\python\python35\lib\site-packages (from virtualenvwrapper-win)
Installing collected packages: virtualenvwrapper-win
  Running setup.py install for virtualenvwrapper-win ... done
Successfully installed virtualenvwrapper-win-1.2.1

E:\ScienceSoft\Python\Django>mkvirtualenv ContentManagePro
Using base prefix 'c:\\users\\administrator\\appdata\\local\\programs\\python\\p
ython35'
New python executable in C:\Users\Administrator\Envs\ContentManagePro\Scripts\py
thon.exe
Installing setuptools, pip, wheel...done.

(ContentManagePro) E:\ScienceSoft\Python\Django>mkvirtualenv minicms
Using base prefix 'c:\\users\\administrator\\appdata\\local\\programs\\python\\p
ython35'
New python executable in C:\Users\Administrator\Envs\minicms\Scripts\python.exe
Installing setuptools, pip, wheel...done.

(minicms) E:\ScienceSoft\Python\Django>django-admin.py startproject mincms

(minicms) E:\ScienceSoft\Python\Django>django-admin.py startproject minicms

(minicms) E:\ScienceSoft\Python\Django>cd minicms

(minicms) E:\ScienceSoft\Python\Django\minicms>python manage.py startapp news
Traceback (most recent call last):
  File "manage.py", line 8, in <module>
    from django.core.management import execute_from_command_line
ImportError: No module named 'django'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "manage.py", line 14, in <module>
    import django
ImportError: No module named 'django'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "manage.py", line 17, in <module>
    "Couldn't import Django. Are you sure it's installed and "
ImportError: Couldn't import Django. Are you sure it's installed and available o
n your PYTHONPATH environment variable? Did you forget to activate a virtual env
ironment?

(minicms) E:\ScienceSoft\Python\Django\minicms>cd..

(minicms) E:\ScienceSoft\Python\Django>env\Scripts\activate
系统找不到指定的路径。

(minicms) E:\ScienceSoft\Python\Django>cd..

(minicms) E:\ScienceSoft\Python>virtualenv
You must provide a DEST_DIR
Usage: virtualenv [OPTIONS] DEST_DIR

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -v, --verbose         Increase verbosity.
  -q, --quiet           Decrease verbosity.
  -p PYTHON_EXE, --python=PYTHON_EXE
                        The Python interpreter to use, e.g.,
                        --python=python2.5 will use the python2.5 interpreter
                        to create the new environment.  The default is the
                        interpreter that virtualenv was installed with (c:\use
                        rs\administrator\appdata\local\programs\python\python3
                        5\python.exe)
  --clear               Clear out the non-root install and start from scratch.
  --no-site-packages    DEPRECATED. Retained only for backward compatibility.
                        Not having access to global site-packages is now the
                        default behavior.
  --system-site-packages
                        Give the virtual environment access to the global
                        site-packages.
  --always-copy         Always copy files rather than symlinking.
  --unzip-setuptools    Unzip Setuptools when installing it.
  --relocatable         Make an EXISTING virtualenv environment relocatable.
                        This fixes up scripts and makes all .pth files
                        relative.
  --no-setuptools       Do not install setuptools in the new virtualenv.
  --no-pip              Do not install pip in the new virtualenv.
  --no-wheel            Do not install wheel in the new virtualenv.
  --extra-search-dir=DIR
                        Directory to look for setuptools/pip distributions in.
                        This option can be used multiple times.
  --download            Download preinstalled packages from PyPI.
  --no-download, --never-download
                        Do not download preinstalled packages from PyPI.
  --prompt=PROMPT       Provides an alternative prompt prefix for this
                        environment.
  --setuptools          DEPRECATED. Retained only for backward compatibility.
                        This option has no effect.
  --distribute          DEPRECATED. Retained only for backward compatibility.
                        This option has no effect.

(minicms) E:\ScienceSoft\Python>virtualenv env
Using base prefix 'c:\\users\\administrator\\appdata\\local\\programs\\python\\p
ython35'
New python executable in E:\ScienceSoft\Python\env\Scripts\python.exe
Installing setuptools, pip, wheel...done.

(minicms) E:\ScienceSoft\Python>cd E:\ScienceSoft\Python\env\Scripts

(minicms) E:\ScienceSoft\Python\env\Scripts>activate.bat

(env) E:\ScienceSoft\Python\env\Scripts>pip install requests
Collecting requests
  Using cached requests-2.18.1-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests)
  Using cached certifi-2017.4.17-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests)
  Using cached chardet-3.0.4-py2.py3-none-any.whl
Collecting idna<2.6,>=2.5 (from requests)
  Using cached idna-2.5-py2.py3-none-any.whl
Collecting urllib3<1.22,>=1.21.1 (from requests)
  Using cached urllib3-1.21.1-py2.py3-none-any.whl
Installing collected packages: certifi, chardet, idna, urllib3, requests
Successfully installed certifi-2017.4.17 chardet-3.0.4 idna-2.5 requests-2.18.1
urllib3-1.21.1

(env) E:\ScienceSoft\Python\env\Scripts>mkvirtualenv minicms
Using base prefix 'c:\\users\\administrator\\appdata\\local\\programs\\python\\p
ython35'
New python executable in C:\Users\Administrator\Envs\minicms\Scripts\python.exe
Installing setuptools, pip, wheel...done.

(minicms) E:\ScienceSoft\Python\env\Scripts>

导入数据:

create_demo_records.py:

# 为数据库添加一些记录

from minicms.wsgi import *
from news.models import Column, Article

def main():

    columns_urls = [

        ('娱乐新闻', 'Play'),
        ('旅游新闻', 'tourist'),
        ('美食新闻', 'Food'),


    ]

    for column_name, url in columns_urls:

        c = Column.objects.get_or_create(name=column_name, slug=url)[0]

        # 创建10篇新闻

        for i in range(1, 11):
            article = Article.objects.get_or_create(

                title='{}_{}'.format(column_name, i),
                slug='article_{}'.format(i),
                content='新闻详细内容: {} {}'.format(column_name, i)


                )[0]

            article.column.add(c)

if __name__ == '__main__':

    main()
    print("Done!")

假设这个文件被保存为 create_demo_records.py (和 manage.py 放在一块,同一个文件夹下)

运行脚本 导入数据:

1
python create_demo_records.py
Done!

终端上显示一个 Done! 就这样 Duang 的一下,数据就导进去了!
Django 开发内容管理系统(第二天)——后台
完善后台的功能,在后台添加,编辑,删除数据

更改 news/admin.py:

from django.contrib import admin

# Register your models here.
from .modelsimport Column, Article

class ColumnAdmin(admin.ModelAdmin):

   list_display = {'name', 'slug', 'intro',}
class ArticleAdmin(admin.ModelAdmin):
   list_display = ('title', 'slug', 'author', 'pub_date', 'update_time')


admin.site.register(Column, ColumnAdmin)
admin.site.register(Article, ArticleAdmin)

创建一个超级管理员(如果你没有后台帐户和密码的话)

修改models.py:
    pub_date = models.DateTimeField('发表时间', auto_now_add=True, editable=True)
    
    update_time = models.DateTimeField('更新时间', auto_now=True, null=True)
E:\ScienceSoft\Python\env\minicms>python manage.py makemigrations news
You are trying to add the field 'pub_date' with 'auto_now_add=True' to article w
ithout a default; the database needs something to populate existing rows.

 1) Provide a one-off default now (will be set on all existing rows)
 2) Quit, and let me add a default in models.py
Select an option:
[default: timezone.now] >>>
# 按Enter,这样就生成如下文件
# 生成了一个对表进行更改的 py 文件在 news/migrations 文件夹中
Migrations for 'news':
  news\migrations\0002_auto_20170724_1626.py
    - Add field pub_date to article
    - Add field update_time to article
# 我们要执行更改
E:\ScienceSoft\Python\env\minicms> python manage.py migrate news
Operations to perform:
  Apply all migrations: news
Running migrations:
  Applying news.0002_auto_20170724_1626... OK

E:\ScienceSoft\Python\env\minicms>
创建一个超级管理员(如果你没有后台帐户和密码的话)
无用户名(默认用户名administrator)+密码L1234567
python manage.py createsuperuser
E:\ScienceSoft\Python\env\minicms>python manage.py runserve
Performing system checks...
这里我们打开开发服务器,访问后台网址,就可以看到:
System check identified no issues (0 silenced).
July 24, 2017 - 16:29:36
Django version 1.11.3, using settings 'minicms.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
http://127.0.0.1:8000/admin用浏览器打开
image.png
image.png

点击栏目——可以查看后台栏目列表

image.png
image.png

我们已经可以在后台进行更改和保存文章了,但是在编辑新闻的时候是不是觉得不爽,没有一个编辑器,我们下面来集成百度的Ueditor 到我们的系统:

集成 DjangoUeditor 编辑器:安装 DjangoUeditor 包
1.把里面的 DjangoUeditor-master 中的 DjangoUeditor 文件夹放到 news 同一级目录,如图所求:

2.在 minicms/settings.py 中加入 DjangoUeditor 这个应用

3.这一段是后来加的,github上没有
我们已经可以在后台进行更改和保存文章了,但是在编辑新闻的时候是不是觉得不爽,没有一个编辑器,我们下面来集成百度的Ueditor 到我们的系统:
为了让上传的图片,文件可以在本地调试的时候可以正常显示,下载,

在 minicms/settings.py 设置 static 和 media

经过上述修改后,再次打开,发现,已经可以使用了:


image.png

后台的功能就讲到这里,大家可以后期自己再进行完善。

提示:其实这里有个 bug, 不同栏目,不同文章网址可以是一样的,先不管这个,我们稍后会修复它

下面我们来完善这三个视图函数(这里为了告诉大家如何做,我们不用通用视图,因为通用视图都帮大家做好了,学不到什么东西)
首页 index 栏目 column 文章详情 article
代码如下:
minicms/new/views.py:


上面是一个大致框架,我们马上完善它,大家看一下参数是如何传递的,可以打开开发服务器 python manage.py runserver
访问比如:http://127.0.0.1:8002/column/tech/ (注意端口,改成你自己的)会得到:

image.png
image.png

我们发现 slug 已经被正确传递到了 views.py 中的视图函数,我们在 views.py 中可以用 slug 检索出相应的栏目或文章。

至此,我们已经知道栏目网址和文章网址的规则,我们现在用代码来生成相关的网址,我们运行 python manage.py shell 进入有项目环境的终端

In [2]: # column

In [3]: reverse('column', args=('tech',))
Out[3]: '/column/tech/'

In [4]: reverse('column', args=('play',))
Out[4]: '/column/play/'

In [5]: reverse('column', args=('Play',))
Out[5]: '/column/Play/'

In [6]: # article

In [7]: reverse('article', args=('article_slug',))
Out[7]: '/news/article_slug/'

In [8]: reverse('article', args=('windows_7',))
Out[8]: '/news/windows_7/'

我们修改 models.py ,将获取网址的功能写成一个函数 get_absolute_url ,然后在模板或其它脚本中调用。

后台默认也会调用这个函数,可以理解成一个约定俗成的名称。
models.py:

from __future__ import unicode_literals
# import os,django
# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "minicms.settings")# project_name 项目名称
# django.setup()
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from DjangoUeditor.models import UEditorField
# from widgets import UEditorWidget,AdminUEditorWidget
# from django.forms.widgets import Widget
from django.core.urlresolvers import reverse
#from django.forms.widgets import *
# Create your models here.
class Column(models.Model):

    name = models.CharField('栏目名称', max_length=256)

    slug = models.CharField('栏目网址', max_length=256, db_index=True)

    intro = models.TextField('栏目简介', default='')

    def __str__(self):

        return self.name
# 将获取网址的功能写成一个函数 get_absolute_url ,然后在模板或其它脚本中调用
    def get_absolute_url(self):

        return reverse('column', args=(self.slug,))

    class Meta:

        verbose_name = '栏目'

        verbose_name_plural = '栏目'

        ordering = ['name'] # 按照哪个栏目排序

class Article(models.Model):

    column = models.ManyToManyField(Column, verbose_name='归属栏目')

    title = models.CharField('标题', max_length=256)

    slug = models.CharField('网址', max_length=256, db_index=True)

    author = models.ForeignKey('auth.user', blank=True, null=True, verbose_name='作者')

    # content = models.TextField('内容', default='', blank=True)
    #仅修改 content 字段
    content = UEditorField('内容', height=300, width=1000,

        default=u'', blank=True, imagePath="uploads/images/",
        toolbars='besttome', filePath='uploads/files/'
        )

    published = models.BooleanField('正式发布', default=True)

    pub_date = models.DateTimeField('发表时间', auto_now_add=True, editable=True)
    
    update_time = models.DateTimeField('更新时间', auto_now=True, null=True)

    def __str__(self):

        return self.title
    def get_absolute_url(self):

        return reverse('article', args(self.slug,))
# 注意 args 参数为元组,写 args=(self.slug) 这样是错的,
# 注意后面有一个逗号 args=(self.slug,)
    class Meta:

        verbose_name = '教程'

        verbose_name_plural = '教程'



注意 args 参数为元组,写 args=(self.slug) 这样是错的,注意后面有一个逗号 args=(self.slug,)
AttributeError Traceback (most recent call last)
<ipython-input-16-c52e47ff1d35> in <module>()
----> 1 c.get_absolute_url()

AttributeError: 'Column' object has no attribute 'get_absolute_url'
原因:需要我们重新进入解释器和注意缩进
我们再次进入 终端 python manage.py shell

In [1]: from news.models import Column, Article

In [2]: c = Column.objects.all()[0]

In [3]: c.get_absolute_url()
Out[3]: '/column/sports/'

In [4]: a = Article.objects.all()[0]

In [5]: a.get_absolute_url()
Out[5]: '/news/article_1/'

In [6]:


我们可以看到这样已经可以获取到文章或者栏目的网址了,下面我们在模板中显示它们。
相关模板文件

我们先写一个 base.html 所有的其它模板都继承它,由于 base.html 不属于某一个 app,它是整个项目共用的,我们建立一个专门的 模块文件夹来放它样的文件。

比如还有其它的 baidutongji.html ,把百度统计的代码放进去来统计访问情况。

我们修改 settings.py,添加一个模板目录 项目下 templates 文件夹。
项目目录下 建一个 templates 文件夹,里面写一个 base.html
修改 settings.py:

 'DIRS': [os.path.join(BASE_DIR, 'templates')], #修改了这一行

项目目录下 建一个 templates 文件夹,里面写一个 base.html

templates/base.html 模板文件:

<!DOCTYPE html>
<html>
   <head>
    <meta charset="utf-8">
    <title>{% blocktitle %}欢迎光临{% endblock title %} - 自强学堂</title>


    {% block css %}

    {% endblock css %}

    {% block js %}

    {% endblock js %}

    </head>

    <body>
    {% block content %}
       <h1> 俊 的 网页</h1>

    {% endblockcontent %}

    {% include "baidutongji.html" %}
    </body>
</html>

templates/baidutongji.html:

<!-- 这里放统计的代码 -->


<!-- 百度统计 begin -->

<div style="display:none" hidden>

<script type="text/javascript">

var _bdhmProtocol = (("https:" == document.location.protocol) ? "http://" : "http://");

document.write(unescape("%3Cscript src='" + _bdhmProtocol +  "hm.baidu.com/h.js%3Fab8b04b0bf640ac196520db1cd029664' type='text/javascript'%3E%3C/script%3E"));


</script>
    
</div>
<!-- 百度统计 end-->


视图中检索结果,渲染到模板中显示出来

我们改写视图函数,查询数据库,得到相关的内容:
views.py:

# -*- coding: utf-8 -*-
from django.shortcuts import render
from django.http import HttpResponse


def index(request):
    return HttpResponse(u'欢迎来 PHPERZ 学习Django')


def column_detail(request, column_slug):
# 改写视图函数,查询数据库,得到相关的内容
    column = Column.objects.get(slug=column_slug)
    return HttpResponse('column slug: ' + column_slug)


def article_detail(request, article_slug):
    article = Article.objects.get(slug=article_slug)
    return render(reuest, 'news/article.html', {'article': article})
 # return HttpResponse('article slug: ' + article_slug)

在 news 下新建 templates 文件夹,再在 templates 下新建 news 文件夹,我们来写两个模板文件:

栏目模板,视图传递过来了一个 column object

<!-- 栏目模板,视图传递过来了一个 column object-->

{% extends "base.html" %}

{% block title %}

{{ colimn.title }}
{% endblock title %}


{% block content %}

栏目简介: {{ column.intro }}
栏目文章列表:
还需要完善
{% endblock content %}

文章模板,视图传递过来了一个 article object

news/templates/news/article.html (或者 项目下的 templates/news/article.html)

<!-- 文章模板,视图传递过来了一个 article object -->

{% extends "base.html" %}

{% block title %}
{{ article.title }}

{% endblock title %}


{% block content %}
<h1> 文章标题: {{ article.title }}</h1>
<div id="main">
    

    {{ article.content }}
    
</div>
{% endblock content %}

我们先在首页显示所有栏目及链接:

news/views.py:

def index(request):
    # 先在首页显示所有栏目及链接
    columns = Column.objects.all()
    return render(request, 'index.html', {'columns': columns})
    #return HttpResponse(u'欢迎来 PHPERZ 学习Django')

项目下 templates/index.html:


们再次在终端测试,安装 bpython,会提示相关的属性和方法

1
python manage.py shell
下面是测试结果
image.png
In [6]: from news.models import Column

In [7]: c = Column.objects.all()[0]

In [8]: c
Out[8]: <Column: 体育新闻>

In [9]: c.article_set.all()
Out[9]: <QuerySet [<Article: 体育新闻_1>, <Article: 体育新闻_2>, <Article: 体育
新闻_3>, <Article: 体育新闻_4>, <Article: 体育新闻_5>, <Article: 体育新闻_6>, <A
rticle: 体育新闻_7>, <Article: 体育新闻_8>, <Article: 体育新闻_9>, <Article: 体
育新闻_10>]>

我们发现用 column.article_set.all() 方法可以获取栏目相关的文章。

我们改一下 news/templates/news/column.html
Django 开发内容管理系统(第三天)
需要添加一个栏目,才可以对其修改一些栏目为首页和导航显示:

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容