每天40分玩转Django:实操图片分享社区

实操图片分享社区

一、今日学习内容概述

学习模块 重要程度 主要内容
模型设计 ⭐⭐⭐⭐⭐ 图片/用户模型、关系设计
视图开发 ⭐⭐⭐⭐⭐ 上传/展示/交互功能
用户系统 ⭐⭐⭐⭐⭐ 注册/登录/权限控制
前端交互 ⭐⭐⭐⭐ 界面设计/Ajax操作

二、模型设计

python 复制代码
# models.py
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from PIL import Image
import uuid

def image_upload_path(instance, filename):
    ext = filename.split('.')[-1]
    return f'images/{uuid.uuid4()}.{ext}'

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField('个人简介', max_length=500, blank=True)
    avatar = models.ImageField('头像', upload_to='avatars/', blank=True)
    following = models.ManyToManyField('self', symmetrical=False, related_name='followers')
    
    def __str__(self):
        return f'{self.user.username}的个人资料'

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
    image = models.ImageField('图片', upload_to=image_upload_path)
    caption = models.TextField('描述', max_length=1000)
    created_at = models.DateTimeField('创建时间', auto_now_add=True)
    likes = models.ManyToManyField(User, related_name='liked_posts', blank=True)
    
    class Meta:
        ordering = ['-created_at']
    
    def __str__(self):
        return f'{self.user.username}的图片 - {self.created_at}'
    
    def get_absolute_url(self):
        return reverse('post_detail', args=[str(self.id)])
    
    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        
        # 处理图片大小
        with Image.open(self.image.path) as img:
            if img.height > 1080 or img.width > 1920:
                output_size = (1920, 1080)
                img.thumbnail(output_size)
                img.save(self.image.path)

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    text = models.TextField('评论内容')
    created_at = models.DateTimeField('创建时间', auto_now_add=True)
    
    class Meta:
        ordering = ['created_at']

三、视图实现

python 复制代码
# views.py
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.core.paginator import Paginator
from .models import Post, Comment, Profile
from .forms import PostForm, CommentForm

@login_required
def upload_post(request):
    if request.method == 'POST':
        form = PostForm(request.POST, request.FILES)
        if form.is_valid():
            post = form.save(commit=False)
            post.user = request.user
            post.save()
            return redirect('post_detail', post.id)
    else:
        form = PostForm()
    return render(request, 'posts/post_create.html', {'form': form})

def post_list(request):
    posts_list = Post.objects.select_related('user').prefetch_related('comments')
    paginator = Paginator(posts_list, 12)
    page = request.GET.get('page')
    posts = paginator.get_page(page)
    return render(request, 'posts/post_list.html', {'posts': posts})

def post_detail(request, post_id):
    post = get_object_or_404(Post, id=post_id)
    comments = post.comments.select_related('user')
    
    if request.method == 'POST':
        comment_form = CommentForm(request.POST)
        if comment_form.is_valid():
            comment = comment_form.save(commit=False)
            comment.post = post
            comment.user = request.user
            comment.save()
            return redirect('post_detail', post_id=post.id)
    else:
        comment_form = CommentForm()
        
    return render(request, 'posts/post_detail.html', {
        'post': post,
        'comments': comments,
        'comment_form': comment_form
    })

@require_POST
@login_required
def like_post(request):
    post_id = request.POST.get('post_id')
    post = get_object_or_404(Post, id=post_id)
    
    if request.user in post.likes.all():
        post.likes.remove(request.user)
        liked = False
    else:
        post.likes.add(request.user)
        liked = True
        
    return JsonResponse({
        'liked': liked,
        'likes_count': post.likes.count()
    })

四、表单设计

python 复制代码
# forms.py
from django import forms
from .models import Post, Comment, Profile

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['image', 'caption']
        widgets = {
            'caption': forms.Textarea(attrs={'rows': 3}),
        }

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ['text']
        widgets = {
            'text': forms.Textarea(attrs={
                'rows': 2,
                'placeholder': '写下你的评论...'
            })
        }

class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['bio', 'avatar']

五、模板实现

html 复制代码
<!-- templates/posts/post_list.html -->
{% extends 'base.html' %}

{% block content %}
<div class="container mt-4">
    <div class="row">
        {% for post in posts %}
            <div class="col-md-4 mb-4">
                <div class="card">
                    <a href="{{ post.get_absolute_url }}">
                        <img src="{{ post.image.url }}" class="card-img-top" alt="{{ post.caption }}">
                    </a>
                    <div class="card-body">
                        <div class="d-flex align-items-center mb-2">
                            <img src="{{ post.user.profile.avatar.url }}" 
                                 class="rounded-circle me-2" 
                                 width="32" height="32">
                            <h6 class="card-title mb-0">{{ post.user.username }}</h6>
                        </div>
                        <p class="card-text text-truncate">{{ post.caption }}</p>
                        <div class="d-flex justify-content-between">
                            <button class="btn btn-sm like-button" 
                                    data-post-id="{{ post.id }}"
                                    data-liked="{{ user in post.likes.all|yesno:'true,false' }}">
                                <i class="fas fa-heart"></i>
                                <span class="likes-count">{{ post.likes.count }}</span>
                            </button>
                            <small class="text-muted">
                                {{ post.created_at|timesince }}前
                            </small>
                        </div>
                    </div>
                </div>
            </div>
        {% endfor %}
    </div>
    
    {% include 'includes/pagination.html' with page=posts %}
</div>
{% endblock %}

<!-- templates/posts/post_detail.html -->
{% extends 'base.html' %}

{% block content %}
<div class="container mt-4">
    <div class="row">
        <div class="col-md-8">
            <img src="{{ post.image.url }}" class="img-fluid">
        </div>
        <div class="col-md-4">
            <div class="card">
                <div class="card-header">
                    <div class="d-flex align-items-center">
                        <img src="{{ post.user.profile.avatar.url }}"
                             class="rounded-circle me-2"
                             width="32" height="32">
                        <h6 class="mb-0">{{ post.user.username }}</h6>
                    </div>
                </div>
                <div class="card-body">
                    <p>{{ post.caption }}</p>
                    <hr>
                    <div class="comments-section">
                        {% for comment in comments %}
                            <div class="comment mb-2">
                                <strong>{{ comment.user.username }}</strong>
                                {{ comment.text }}
                                <small class="text-muted d-block">
                                    {{ comment.created_at|timesince }}前
                                </small>
                            </div>
                        {% endfor %}
                    </div>
                    {% if user.is_authenticated %}
                        <form method="post" class="mt-3">
                            {% csrf_token %}
                            {{ comment_form }}
                            <button type="submit" class="btn btn-primary btn-sm mt-2">
                                发表评论
                            </button>
                        </form>
                    {% endif %}
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}

六、流程图

七、JavaScript交互

javascript 复制代码
// static/js/main.js
document.addEventListener('DOMContentLoaded', function() {
    // 图片点赞功能
    document.querySelectorAll('.like-button').forEach(button => {
        button.addEventListener('click', function() {
            const postId = this.dataset.postId;
            const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
            
            fetch('/posts/like/', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'X-CSRFToken': csrftoken
                },
                body: `post_id=${postId}`
            })
            .then(response => response.json())
            .then(data => {
                const icon = this.querySelector('i');
                const count = this.querySelector('.likes-count');
                
                if (data.liked) {
                    icon.classList.add('text-danger');
                } else {
                    icon.classList.remove('text-danger');
                }
                count.textContent = data.likes_count;
            });
        });
    });
    
    // 图片上传预览
    const imageInput = document.querySelector('input[type="file"]');
    if (imageInput) {
        imageInput.addEventListener('change', function() {
            const file = this.files[0];
            if (file) {
                const reader = new FileReader();
                reader.onload = function(e) {
                    document.querySelector('#preview-image').src = e.target.result;
                }
                reader.readAsDataURL(file);
            }
        });
    }
});

八、常见功能扩展

  1. 图片过滤器
python 复制代码
from PIL import Image, ImageEnhance

def apply_filter(image, filter_name):
    """应用图片滤镜"""
    img = Image.open(image)
    
    if filter_name == 'grayscale':
        return img.convert('L')
    elif filter_name == 'brightness':
        enhancer = ImageEnhance.Brightness(img)
        return enhancer.enhance(1.5)
    # 添加更多滤镜...
    
    return img
  1. 图片标签系统
python 复制代码
class Tag(models.Model):
    name = models.CharField(max_length=50, unique=True)
    
    def __str__(self):
        return self.name

class Post(models.Model):
    # ... 其他字段 ...
    tags = models.ManyToManyField(Tag, blank=True)
  1. 收藏功能
python 复制代码
class Collection(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    posts = models.ManyToManyField(Post, related_name='collections')
    name = models.CharField(max_length=100)
    created_at = models.DateTimeField(auto_now_add=True)

通过本章学习,你应该能够:

  1. 设计和实现图片分享系统
  2. 处理用户认证和权限
  3. 实现图片上传和处理
  4. 开发社交互动功能

怎么样今天的内容还满意吗?再次感谢朋友们的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!

相关推荐
sp_fyf_202417 分钟前
【大语言模型】ACL2024论文-35 WAV2GLOSS:从语音生成插值注解文本
人工智能·深度学习·神经网络·机器学习·语言模型·自然语言处理·数据挖掘
AITIME论道18 分钟前
论文解读 | EMNLP2024 一种用于大语言模型版本更新的学习率路径切换训练范式
人工智能·深度学习·学习·机器学习·语言模型
ROCKY_8171 小时前
Mysql复习(二)
数据库·mysql·oracle
Dovir多多1 小时前
Python数据处理——re库与pydantic的使用总结与实战,处理采集到的思科ASA防火墙设备信息
网络·python·计算机网络·安全·网络安全·数据分析
明明真系叻1 小时前
第二十六周机器学习笔记:PINN求正反解求PDE文献阅读——正问题
人工智能·笔记·深度学习·机器学习·1024程序员节
88号技师3 小时前
2024年12月一区SCI-加权平均优化算法Weighted average algorithm-附Matlab免费代码
人工智能·算法·matlab·优化算法
IT猿手3 小时前
多目标应用(一):多目标麋鹿优化算法(MOEHO)求解10个工程应用,提供完整MATLAB代码
开发语言·人工智能·算法·机器学习·matlab
88号技师3 小时前
几款性能优秀的差分进化算法DE(SaDE、JADE,SHADE,LSHADE、LSHADE_SPACMA、LSHADE_EpSin)-附Matlab免费代码
开发语言·人工智能·算法·matlab·优化算法
2301_764441333 小时前
基于python语音启动电脑应用程序
人工智能·语音识别
HyperAI超神经3 小时前
未来具身智能的触觉革命!TactEdge传感器让机器人具备精细触觉感知,实现织物缺陷检测、灵巧操作控制
人工智能·深度学习·机器人·触觉传感器·中国地质大学·机器人智能感知·具身触觉