📜  使用 Django 框架的笑话应用项目(1)

📅  最后修改于: 2023-12-03 14:49:38.897000             🧑  作者: Mango

使用 Django 框架的笑话应用项目

为了学习和练习 Django 框架,我们可以开发一个笑话应用项目,这个项目可以让用户浏览和分享各种有趣的笑话。

项目架构

我们可以把项目的架构设计成以下几个模块:

  1. 用户模块:这个模块用于用户注册、登录和退出登录等功能。我们可以使用 Django 内置的用户认证系统实现这个模块。
  2. 笑话模块:这个模块用于存储和管理所有的笑话,包括添加、编辑、删除和浏览等功能。我们可以使用 Django 的模型来实现这个模块,并为每个笑话增加一个点赞和评论功能。
  3. 分类模块:这个模块用于存储和管理所有的笑话分类,包括添加、编辑、删除和浏览等功能。我们也可以使用 Django 的模型来实现这个模块。
项目目录结构

创建项目目录结构如下:

project
├── app             # Django 应用目录
│   ├── migrations # 迁移文件目录
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── project         # Django 项目目录
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── templates       # 模板目录
    ├── base.html
    ├── index.html
    └── joke.html
数据库设计

我们可以使用 SQLite 数据库来存储数据,数据库表的设计如下:

用户表

| 字段名 | 类型 | 描述 | | --------- | -------- | ---------- | | id | integer | 用户 ID | | username | varchar | 用户名 | | password | varchar | 密码 | | email | varchar | 邮箱 | | join_date | datetime | 加入时间 |

笑话分类表

| 字段名 | 类型 | 描述 | | ------ | ------- | -------- | | id | integer | 分类 ID | | name | varchar | 分类名称 |

笑话表

| 字段名 | 类型 | 描述 | | ----------- | -------- | ---------------- | | id | integer | 笑话 ID | | title | varchar | 笑话标题 | | content | text | 笑话内容 | | create_time | datetime | 笑话创建时间 | | update_time | datetime | 笑话最后更新时间 | | category_id | integer | 笑话分类 ID |

评论表

| 字段名 | 类型 | 描述 | | ----------- | -------- | ------------------ | | id | integer | 评论 ID | | user_id | integer | 用户 ID | | joke_id | integer | 笑话 ID | | content | text | 评论内容 | | create_time | datetime | 评论创建时间 | | update_time | datetime | 评论最后更新时间 | | parent_id | integer | 父级评论的评论 ID |

代码实现
应用配置

app 目录下的 apps.py 文件中添加应用配置:

class JokeConfig(AppConfig):
    name = 'app'
    verbose_name = '笑话应用'

project 目录下的 settings.py 文件中添加应用配置和静态资源路径:

INSTALLED_APPS = [
    # ...
    'app.apps.JokeConfig',
    # ...
]

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]
数据模型

app 目录下的 models.py 文件中定义数据模型:

class Category(models.Model):
    name = models.CharField(max_length=50, unique=True)

class Joke(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    create_time = models.DateTimeField(auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)

class User(models.Model):
    username = models.CharField(max_length=50, unique=True)
    password = models.CharField(max_length=50)
    email = models.EmailField()
    join_date = models.DateTimeField(auto_now_add=True)

class Comment(models.Model):
    content = models.TextField()
    create_time = models.DateTimeField(auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    joke = models.ForeignKey(Joke, on_delete=models.CASCADE)
    parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE)
视图函数

app 目录下的 views.py 文件中编写视图函数:

def index(request):
    categories = Category.objects.all()
    jokes = Joke.objects.all()
    return render(request, 'index.html', {'categories': categories, 'jokes': jokes})

def joke(request, id):
    joke = get_object_or_404(Joke, id=id)
    comments = Comment.objects.filter(joke=id, parent=None).order_by('-create_time')
    context = {
        'joke': joke,
        'comments': comments,
        'comment_form': CommentForm()
    }
    return render(request, 'joke.html', context)

def add_comment(request, id):
    joke = get_object_or_404(Joke, id=id)
    form = CommentForm(request.POST)
    if form.is_valid():
        comment = form.save(commit=False)
        comment.user = request.user
        comment.joke = joke
        comment.save()
        return redirect('joke', id)
    comments = Comment.objects.filter(joke=id, parent=None).order_by('-create_time')
    context = {
        'joke': joke,
        'comments': comments,
        'comment_form': form
    }
    return render(request, 'joke.html', context)
URL 路由

app 目录下的 urls.py 文件中设置 URL 路由:

from django.urls import path
from .views import index, joke, add_comment

urlpatterns = [
    path('', index, name='index'),
    path('joke/<int:id>/', joke, name='joke'),
    path('joke/<int:id>/comment/', add_comment, name='add_comment'),
]

在项目目录下的 urls.py 文件中添加应用 URL 路由:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('app.urls')),
]
模板文件

templates 目录下的 index.html 文件中编写首页模板:

{% extends 'base.html' %}

{% block content %}
<h1>笑话分类</h1>
{% for category in categories %}
<a href="#">{{ category.name }}</a>
{% endfor %}

<h1>笑话列表</h1>
<ul>
{% for joke in jokes %}
<li><a href="{% url 'joke' joke.id %}">{{ joke.title }}</a></li>
{% endfor %}
</ul>
{% endblock %}

templates 目录下的 joke.html 文件中编写笑话详情页模板:

{% extends 'base.html' %}

{% block content %}
<h1>{{ joke.title }}</h1>
<p>{{ joke.content }}</p>

<h2>评论</h2>
<ul>
{% for comment in comments %}
<li>
    {{ comment.content }}
    <p>
    发表于{{ comment.create_time }}, {{ comment.user.username }} 说:
    <a href="#comment-form">回复</a>
    </p>
    <ul>
    {% for reply in comment.comment_set.all %}
    <li>
        {{ reply.content }}
        <p>
        发表于{{ reply.create_time }}, {{ reply.user.username }} 回复:
        </p>
    </li>
    {% endfor %}
    </ul>
    <hr>
</li>
{% endfor %}
</ul>

<h2>添加评论</h2>
<form method="post" action="{% url 'add_comment' joke.id %}" id="comment-form">
{% csrf_token %}
{{ comment_form.as_p }}
<input type="submit" value="提交">
</form>
{% endblock %}

templates 目录下的 base.html 文件中编写基础模板:

<!DOCTYPE html>
<html>
<head>
    <title>笑话应用</title>
</head>
<body>
    <header>
        <h1><a href="{% url 'index' %}">笑话应用</a></h1>
        <nav>
            <a href="#">分类</a>
            {% if user.is_authenticated %}
            <a href="{% url 'logout' %}">退出</a>
            {% else %}
            <a href="{% url 'login' %}">登录</a>
            <a href="{% url 'register' %}">注册</a>
            {% endif %}
        </nav>
    </header>
    <main>
        {% block content %}
        {% endblock %}
    </main>
</body>
</html>
总结

通过这个笑话应用项目的开发,我们可以熟悉使用 Django 框架来实现一个 Web 应用的基本流程,包括数据模型的设计、视图函数的编写、URL 路由的设置和模板文件的编写等。

这个项目还有许多需要完善的地方,比如用户认证、数据验证、搜索和排序等功能,可以继续在这个基础上进行拓展。