您的位置:首页 > 运维架构 > 网站架构

Django之博客系统:在网站中分享内容(一)

2018-04-01 22:18 465 查看

在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后图片上传成功,进入后台后可以查看到上传的图片信息,其中包括上传路径,上传的用户

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: