在models.py中添加image模型:

class Image(models.Model):

user=models.ForeignKey(settings.AUTH_USER_MODEL,related_name='image_created')

title=models.CharField(max_length=200)

url=models.URLField()

image=models.ImageField(upload_to='images/%Y/%m/%d')

descriptions=models.TextField(blank=True)

created=models.DateTimeField(default=timezone.now)

user_like=models.ManyToManyField(settings.AUTH_USER_MODEL,related_name="image_liked",blank=True)

def __str__(self):

return self.title

1 user:标记了这张图片 User 对象。这是一个 ForeignKey字段,因为它指定了一个一对多关系: 一个用户可以 post 多张图片, 但是每张图片只能由一个用户上传

2 user_like: 当你定义一个ManyToMany字段时,Django 会用两张表主键(primary key)创建一个中介联接表。ManyToMany字段可以在任意两个相关联的表中创建。同ForeignKey字段一样,ManyToMany字段的related_name属性使我们可以命名另模型回溯(或者是反查)到本模型对象的关系。ManyToMany字段提供了一个多对多管理器(manager),这个管理器使我们可以回溯相关联的对象比如:image.users_like.all()或者从一个user中回溯,比如:user.images_liked.all()。

3 models.ImageField(upload_to='images/%Y/%m/%d')制定了图片上传的路径。

同步数据库:

zhf@zhf-maple:~/py_prj/mysite$ python manage.py makemigrations

Migrations for 'blog':

blog/migrations/0006_image.py

- Create model Image

zhf@zhf-maple:~/py_prj/mysite$ python manage.py migrate

Operations to perform:

Apply all migrations: admin, auth, blog, contenttypes, sessions, taggit

Running migrations:

Applying blog.0006_image... OK

在forms.py中定义ImageCreateForm提交图片的表单

class ImageCreateForm(forms.ModelForm):

class Meta:

model=Image

fields=('title','url','descriptions')

widgets={'url':forms.HiddenInput,}

def clean_url(self):

url=self.cleaned_data['url']

valid_extensions=['jpg','jpeg']

extensions=url.rsplit('.',1)[1].lower()

if extensions not in valid_extensions:

raise forms.ValidationError('The given url does not match valid image extensions')

return url

为了验证提供的图片 URL 是否合法,我们将检查以.jpg或.jpeg结尾的文件名,来只允许JPG文件的上传。Django允许你自定义表单方法来清洁特定的字段,通过使用以clean_<fieldname>形式命名的方法来实现。这个方法会在你为一个表单实例执行is_valid()时执行。在清洁方法中,你可以改变字段的值或者为某个特定的字段抛出错误当需要的时候,将下面这个方法添加进ImageCreateForm。

clean_url: 从表单实例的cleaned_data字典中获取url字段的值

extensions:通过分类URL来获取文件扩展名,然后检查它是否为合法扩展名之一,如果不是合法的扩展名,就会抛出ValidationError异常

在ImageCreateForm中重写save函数。

def save(self, force_insert=False,force_update=False,commit=True):

image=super(ImageCreateForm,self).save(commit=False)

image_url=self.cleaned_data['url']

image_name=self.title

response=request.urlopen(image_url)

image.image.save(image_name,ContentFile(response.read()),save=False)

if commit:

image.save()

return image

上面的这段代码:

1 调用save()方法从表单中新建了一个image对象,并且commit=False

2 从表单的cleaned_data字典中获取了 URL

3 生成图片的名字

4使用 Python 的 urllib3 模块来下载图片,然后我们调用save()方法把图片传递给一个ContentFile对象,这个对象被下载的文件所实例化。这样,我们就可以将我们的文件保存到项目中的 media 路径下。我们传递了参数comiit=False来避免对象被保存到数据库中。

4 为了保持和我们覆写的save()方法一样的行为,我们将在commit参数为Ture时保存表单到数据库中

接下来需要在views.py中添加一个新的视图来控制我们的表单,编辑views.py文件,然后添加image_create方法:

@login_required(login_url='/account/login')

def image_create(request):

if request.method=='POST':

form=ImageCreateForm(data=request.POST)

if form.is_valid():

cd=form.cleaned_data

new_item=form.save(commit=False)

new_item.user=request.user

new_item.save()

messages.success(request,'image added successfully')

return redirect(new_item.url)

else:

form=ImageCreateForm(data=request.GET)

return render(request,'blog/create.html',{'section':'images','form':form})

1 image_create添加了login_required装饰器来判断是否有用户登录

2 new_item.user=request.user进行用户和图片的绑定,这样就知道了是谁上传的这个图片

3 然后将image对象保存到了数据库中

在blog应用的urls.py中添加路由:

url(r'^create/$',views.image_create,name='create')

在主应用的urls.py中添加路由:

url(r'^image/',include('blog.urls'))

在templates/blog下添加create.html。代码如下:

{% extends "blog/base.html" %}

{% block title %}给图片加标签{% endblock %}

{% block content %}

<h1>给图片加标签</h1>

<img src="{{ request.GET.url }}" class="image-preview">

<form action="." method="post">

{{ form.as_p }}

{% csrf_token %}

<input type="submit" value="Bookmark it!">

</form>

{% endblock %}

在浏览器中输入http://127.0.0.1:8000/image/create/?title=picture&url=http://upload.wikimedia.org/wikipedia/commons/8/85/Django_Reinhardt_and_Duke_Ellington_(Gottlieb).jpg

得到的效果如下:

点击Bookmark it后图片上传成功,进入后台后可以查看到上传的图片信息,其中包括上传路径,上传的用户

Django之博客系统:在网站中分享内容(一)的更多相关文章

  1. Django(博客系统):基于pycharm如何一个django工程下创建多个app

    背景:通常我们创建一个django系统时,为了把业务模块划分清楚往往会把一个独立的业务模块放到一个app中,如果多个独立的业务模块就会创建多个app,一般情况下为了更好的管理这些app,会把他们都存放 ...

  2. Django练习——博客系统小试

    在上一篇博客Todolist的基础上(http://blog.csdn.net/hcx25909/article/details/24251427),本周继续进行实践,这次我要搭建一个简单的博客系统. ...

  3. 纯django开发博客系统

    企业级教程:纯django开发博客系统 1.视频教程 https://www.duanshuilu.com/ 2.教程文档 https://www.duanshuilu.com/ 0.课程简介1.简价 ...

  4. 【django之博客系统开发】

    一.项目简介 使用django开发一套博客系统,参考博客园. 需求如下: 项目结构: 二.全部代码 from django.db import models # Create your models ...

  5. Django之博客系统邮件分享博客

    在上一章中,我们创建了一个基础的博客应用,我们能在http://127.0.0.1:8000/blog/显示我们的博客.在这一章我们将尝试给博客系统添加一些高级的特性,比如通过email来分享帖子,添 ...

  6. Django之博客系统搭建一

    前面已经介绍了django的各种用法,从这一章开始,将实际搭建一个blog系统. 首先我们需要设计blog的模型,在models.py中添加如下内容 # -*- coding: utf-8 -*- f ...

  7. Django之博客系统:用户登陆

    使用django有一个好处就是有各种各样的框架可以拿来直接使用.相比flask,django自带的框架确实要多很多.比如这一章就要介绍的用户登录.Django拥有一个内置的认证(authenticat ...

  8. Django之博客系统:增加评论

    3既然是博客,那肯定就有留言评论系统.在这一章就来建立一个评论系统. 1 创建一个模型来保存评论 2 创建一个表单来提交评论并且验证输入的数据 3 添加一个视图函数来处理表单和保存新的评论到数据库 4 ...

  9. Django之博客系统:自定义模板标签

    Django提供了很多内置的模板标签比如{% if %}或者{% block %}Django也允许你创建自己的模板标签(template tags)来执行自定义的动作.当你需要在你的模板中添加功能而 ...

  10. Django之博客系统:增加标签

    一般在发表博客后会给每个帖子加上一个标签.类似帖子关键字的功能.在这一章中来看下如何给博客添加标签功能(tagging) 添加标签需要集成第三方的Django标签应用来完成这个功能.django-ta ...

随机推荐

  1. Process使用

    最近在一个项目中,需要在C#中调用cmd窗口来执行一个命令,使用到了Process这个类,使用过程中遇到不少问题,好在终于解决了.赶紧记录下来. Process process = new Proce ...

  2. mybatis 学习四 (上)resutlMap

    SQL 映射XML 文件是所有sql语句放置的地方.需要定义一个workspace,一般定义为对应的接口类的路径.写好SQL语句映射文件后,需要在MyBAtis配置文件mappers标签中引用,例如: ...

  3. C# Dynamic通用反序列化Json类型并遍历属性比较

    背景 : 最近在做JAVA 3D API重写,重写的结果需要与原有的API结果进行比较,只有结果一致时才能说明接口是等价重写的,为此需要做一个API结果比较的工具,比较的内容就是Json内容,但是为了 ...

  4. 开发环境入门 linux基础 (部分)while for 函数 计划任务

    while循环 while do 动作 done 需要无限循环时我们会选择while : echo -e 格式处理,将\n的意义不变. exit 指退出执行程序 break 指跳出本层循环 conti ...

  5. 2016.7.10 SqlServer语句中类似decode、substr、instr、replace、length等函数的用法

    Decode() 对应 case when函数 case CHARINDEX('/',start_point_name) when 0 then start_point_name else subst ...

  6. 2015.1.15 利用Oracle函数插入表结构 Bulk collect into 不用循环,简洁高效

    如果表结构只对应一个字段,可以 select col1 bulk collect into 变量,不用游标循环,简洁高效 create or replace function get_airway_s ...

  7. Diag:Diagonal matrices and diagonals of a matrix

    Diag:Diagonal matrices and diagonals of a matrix Syntax X = diag(v,k) X = diag(v) v = diag(X,k) v =  ...

  8. 使用mui框架后a标签无法跳转

    由于最近工作项目上使用到前台mui框架,笔者在将H5转换为jsp时,遇见各种各样问题,原因归结为对mui框架不熟悉,今天就遇见一个特别奇怪的问题,界面中超链接<a>标签无法跳转,笔者试着添 ...

  9. java中的自动转型的学习理解

    java当中的继承是和c++中的继承类似,只是java中的继承时的父类只能有一位. 我们今天在这里讲的是关于java中的自动转型的理解:顾名思义,自动转型值得就是使用时自动的将自身的类型进行转化. 自 ...

  10. linux系统 使用git图形化管理工具———gitk

    运行安装命令: sudo apt-get install gitk 运行命令打开gitk : gitk