python - 如何在django上发布图片?
问题描述
我一直在尝试使我的代码能够发布图像,但是当我创建帖子时,图片不会出现,但图像会保存在媒体/图像上我想知道是否有任何方法可以使代码工作,可能是什么当我调用图像 {{ request.user.image.url }} 时,base.html 中的错误
视图.py
def create(request):
if request.method == 'POST':
created_date = timezone.now()
header1 = request.POST['header']
content1 = request.POST['content']
user = request.user
uploded_file = request.FILES['image']
created_obj = Create.objects.create(added_date=created_date, title=header1, content=content1, user=user, image=uploded_file)
created_obj.save()
print('create created')
return redirect('home')
else:
print('create not created')
return render(request, 'create.html')
模型.py
class Create(models.Model):
added_date = models.DateTimeField()
title = models.CharField(max_length=200)
content = models.CharField(max_length=200)
image = models.ImageField(null=True, blank=True, upload_to='images/')
user = models.ForeignKey(User, related_name='user', on_delete=models.CASCADE, default=1)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
创建.html
{% extends 'home.html' %}
{% block body %}
<div style="margin-top: 200px; margin-left:200px;">
<form action="create" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" name="header" placeholder="Add here...">
<input type="text" name="content" placeholder="Add here...">
<input type="file" name="image">
<button type="submit"name="action" class="btn btn-primary mb-2">submit</button>
</form>
</div>
{% endblock %}
base.html
{% extends 'home.html' %}
{% block body %}
<ul action="{% url 'create' %}" class="container-sm list-group" style="margin-top: 200px;">
{% for created_post in created_posts %}
<li class="list-group-item">{{ created_post.title }}
<a href="{% url 'profile_pk' pk=created_post.user.pk %}">{{ created_post.user }}</a>
<img class="image" src="{{ create.image.url }}">
<p>{{ created_post.content }}</p>
<div class="float-right">
<form action="delete_create/{{ created_post.id }}/" action="post">
<button type="submit" class="btn btn-outline-danger btn-sm">Delete</button>
</form>
</div>
<div class="float-right">
<a href="{% url 'edit' created_post.id %}" class="btn btn-outline-warning btn-sm" style="margin-right: 5px;" role="button">Edit</a>
</div>
</li>
{% endfor %}
</ul>
{% endblock %}
解决方案
在大多数网站中,我们经常处理图像,文件等媒体数据。在django中,我们可以借助模型字段ImageField来处理图像。
在本文中,我们在名为 image_upload 的示例项目中创建了应用程序 image_app。
第一步是在 settings.py 文件中添加以下代码。
filter_none
brightness_4
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
MEDIA_ROOT 用于在计算机中存储文件的服务器路径。MEDIA_URL 是浏览器通过 Http 访问文件的参考 URL。
在 urls.py 我们应该像这样编辑配置
如果设置。调试:
urlpatterns += 静态(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
示例 models.py 应该是这样的,因为我们创建了一个酒店模型,其中包含酒店名称及其图像。在这个项目中,我们从酒店预订网站的用户那里获取酒店名称及其图像。
filter_none
brightness_4
# models.py
class Hotel(models.Model):
name = models.CharField(max_length=50)
hotel_Main_Img = models.ImageField(upload_to='images/')
//Here upload_to will specify, to which directory the images should reside, by default django creates the directory under media directory which will be automatically created when we upload an image. No need of explicit creation of media directory.
我们必须在 image_app 下创建一个 forms.py 文件,这里我们处理的是模型表单,以使内容更易于理解。
filter_none
brightness_4
# forms.py
from django import forms
from .models import *
class HotelForm(forms.ModelForm):
class Meta:
model = Hotel
fields = ['name', 'hotel_Main_Img']
Django 将隐式处理表单验证,而无需在脚本中显式声明,它会根据我们在 models.py 文件中指定的模型字段在页面中创建类似的表单字段。这就是模型形式的优势。
现在在 image_app 下创建一个模板目录,我们必须创建一个用于上传图像的 html 文件。HTML 文件应如下所示。
filter_none
edit
play_arrow
brightness_4
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hotel_image</title>
</head>
<body>
<form method = "post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
</body>
</html>
在发出 POST 请求时,我们必须以某种方式对构成请求主体的数据进行编码。所以,我们必须在表单标签中指定编码格式。multipart/form-data 要复杂得多,但它允许将整个文件包含在数据中。
csrf_token 用于防止跨站点请求伪造。
form.as_p 只是将所有元素包装在 HTML 段落标签中。优点是不必在模板中编写循环来显式添加 HTML 来包围每个标题和字段。
在 image_app 下的 views.py 中,我们必须编写一个视图来接收用户的请求并返回一些 html 页面。
filter_none
brightness_4
from django.http import HttpResponse
from django.shortcuts import render, redirect
from .forms import *
# Create your views here.
def hotel_image_view(request):
if request.method == 'POST':
form = HotelForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('success')
else:
form = HotelForm()
return render(request, 'hotel_image_form.html', {'form' : form})
def success(request):
return HttpResponse('successfully uploaded')
每当 hotel_image_view 命中并且该请求是 POST 时,我们正在创建一个模型表单实例 form = HotelForm(request.POST, request.FILES) 图像将存储在 request.FILES 之一下。如果有效,则保存到数据库中并重定向到成功 url,表示图像上传成功。如果方法不是 POST,我们将使用创建的 html 模板进行渲染。
urls.py 看起来像这样——</p>
filter_none
brightness_4
from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from .views import *
urlpatterns = [
path('image_upload', hotel_image_view, name = 'image_upload'),
path('success', success, name = 'success'),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT) `enter code here`
推荐阅读
- javascript - 尝试使用 Node.JS 将 JSON 插入 MySQL
- c# - 动态创建的面板的访问控制
- java - Apache Storm 1.1.0 未运行并给出无法从客户端 sessionid 读取附加数据
- javascript - 比较这两个时间戳我做错了什么?
- python - 如何在python中以网格格式从html表中获取数据
- r - R非重叠样本 - 更快的功能
- javascript - 此代码段中的加法器是什么?我找不到答案
- firebase - Firebase Admin Node.js SDK 没有 firebase.firestore.FieldValue.increment。我应该使用 Firebase JavaScript SDK(客户端)吗?
- sql - 如果 '" \ 被过滤,sql注入是否有效
- php - laravel 中是否有有效的方法从数据库中选择记录并将其设置为 user_id?