Django部分
Django DEMO地址 ios-swift DEMO地址
1. 軟體環境:
django ~1.11
Python 3.6.1
Anaconda 4.4.0
Mac sbulime
2. 新建專案
django-admin.py startproject django_uploadImg_userHeadChange_rest
複製程式碼
3. 新建APP
python manage.py startapp upload_test
複製程式碼
4. 新建 mySerializers.py檔案,專案構成如下
5. models.py
from django.db import models
class haveFunUser(models.Model):
user_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=128)
phone = models.CharField(max_length=11,unique=True)
date_joined = models.DateTimeField(auto_now=True) #DateField
gender_choices = ((0,"男"),(1,"女"))
sex = models.IntegerField(choices=gender_choices,default=1)
age = models.PositiveIntegerField(default=18)
address = models.CharField(max_length=80,null=True,blank=True)
email = models.EmailField(null=True,blank=True)
img = models.TextField(null=True,blank=True)
user_type_choice=((0,"超級使用者"),(1,"普通使用者"))
user_type = models.IntegerField(choices=user_type_choice,default=1)
passwd = models.CharField(max_length=64)
def __str__(self):
return self.name,self.phone
class userHeadImage(models.Model):
image_id = models.AutoField(primary_key=True)
image = models.ImageField(max_length=None,upload_to='head_images',null=True, blank=True)
uploaded_by = models.ForeignKey(haveFunUser)
複製程式碼
6. mySerializers.py
from django.contrib.auth.models import *
from rest_framework import serializers
from . import models
import time
from django.conf import settings
class ImageSerializer(serializers.ModelSerializer):
image = serializers.ImageField(max_length=None, use_url=True) #use_url=True是否顯示完整的路徑
def create(self, validated_data):
data = self.context.get('request').data.dict()
user_id = data['user_id']
print('xxxx=------',user_id,'xasaaaaa=---',validated_data)
validated_data.update({'uploaded_by_id': user_id})
return models.userHeadImage.objects.create(**validated_data)
class Meta:
model = models.userHeadImage
fields = ('image_id','image')
#使用者基本資訊
class UserSerializer(serializers.ModelSerializer):
time_join = serializers.SerializerMethodField()
img = serializers.SerializerMethodField()
def get_time_join(self,obj):
t = obj.date_joined
return t.strftime('%Y-%m-%d %X')
def get_img(self,obj):
image = ImageSerializer(models.userHeadImage.objects.filter(uploaded_by_id__exact=obj.user_id).first()).data
if image:
return image['image']
else:
return ''
class Meta:
model = models.haveFunUser
fields = ('user_id','name', 'phone','time_join','sex','age','address','email','img','user_type','passwd')
複製程式碼
7. settings.py
註冊APP
INSTALLED_APPS = [
'rest_framework',
'upload_test',
]
複製程式碼
要想外網內網都能訪問需要:
ALLOWED_HOSTS = ['*']
複製程式碼
設定影象儲存的檔案路徑以及獲取影象的網路路徑
MEDIA_ROOT = os.path.join(BASE_DIR, 'image')
MEDIA_URL = '/media/'
複製程式碼
REST_FRAMEWORK設定
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.AllowAny',),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGINATE_BY': 10,
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
'rest_framework.parsers.FileUploadParser'
),
}
複製程式碼
8. 在django_uploadImg_userHeadChange_rest下的urls.py中配置自己APP的URL檔案
from django.conf.urls import url,include
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api-auth/',include('rest_framework.urls', namespace='rest_framework')),
url(r'^haveFun/', include('upload_test.urls',namespace='haveFun')),
]+ static(settings.MEDIA_URL , document_root=settings.MEDIA_ROOT )
複製程式碼
9. views.py
#encoding:utf-8
from __future__ import unicode_literals
from django.shortcuts import render
from . import mySerializers as serializers
from upload_test import models
from django.http import HttpResponse
import json
from rest_framework import viewsets
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import *
from rest_framework import permissions
from rest_framework.status import HTTP_200_OK, HTTP_400_BAD_REQUEST
from rest_framework import generics
from rest_framework import mixins
from rest_framework.views import APIView
class JSONResponse(HttpResponse):
def __init__(self, data, **kwargs):
content = JSONRenderer().render(data)
kwargs['content_type'] = 'application/json'
super(JSONResponse, self).__init__(content, **kwargs)
class imageAPI(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = models.userHeadImage.objects.all()
serializer_class = serializers.ImageSerializer
def post(self, request, *args, **kwargs):
data = request.data.dict()
user_id = data['user_id']
m = models.userHeadImage.objects.filter(uploaded_by_id__exact=user_id)
for model in m:
model.image.delete()
print(model.image)
model.delete()
try:
self.create(request, *args, **kwargs)
image = models.userHeadImage.objects.get(uploaded_by_id__exact=user_id)
return JSONResponse({'result':serializers.ImageSerializer(image).data,'desc':'upload success'}, status=HTTP_200_OK)
except:
return JSONResponse({'desc':'upload faile'},status=HTTP_400_BAD_REQUEST)
class UploadViewSet(imageAPI):
queryset = models.userHeadImage.objects.all()
serializer_class = serializers.ImageSerializer
parser_classes = (MultiPartParser, )
#用於登入
class UserLoginAPIView(APIView):
queryset = models.haveFunUser.objects.all()
serializer_class = serializers.UserSerializer
permission_classes = (permissions.AllowAny,)
def post(self, request, format=None):
data = request.data
username = data.get('name')
password = data.get('passwd')
if not models.haveFunUser.objects.filter(name__exact=username):
return JSONResponse({'desc':'使用者名稱不存在'},status=HTTP_200_OK,)
user = models.haveFunUser.objects.get(name__exact=username)
if user.passwd == password:
serializer = serializers.UserSerializer(user)
new_data = serializer.data
print(new_data)
# 記憶已登入使用者
self.request.session['user_id'] = user.user_id
self.request.session['user_name'] = user.name
return JSONResponse({'result':serializer.data,'desc':'登陸成功'}, status=HTTP_200_OK)
return JSONResponse( {'desc':'password error'},status=HTTP_200_OK)
#用於註冊
class UserRegisterAPIView(APIView):
queryset = models.haveFunUser.objects.all()
serializer_class = serializers.UserSerializer
permission_classes = (permissions.AllowAny,)
def post(self, request, format=None):
data = request.data
username = data.get('name')
phone = data.get('phone')
print('registrt--->',data)
dic = {}
if models.haveFunUser.objects.filter(name__exact=username):
return JSONResponse({'desc':'使用者名稱已存在'},status=HTTP_400_BAD_REQUEST)
if models.haveFunUser.objects.filter(phone__exact=phone):
return JSONResponse({'desc':'手機號碼已存在'},status=HTTP_400_BAD_REQUEST)
serializer = serializers.UserSerializer(data=data)
if serializer.is_valid(raise_exception=True):
serializer.save()
dic['result'] = serializer.data
dic['desc']='註冊成功'
return JSONResponse(dic,status=HTTP_200_OK)
return JSONResponse({'desc':serializer.errors}, status=HTTP_400_BAD_REQUEST)
複製程式碼
10. APP中urls.py配置
from django.conf.urls import url,include
from . import views
urlpatterns = [
url(r'^upload_head_image$', views.UploadViewSet.as_view()),
url(r'^register$', views.UserRegisterAPIView.as_view()),
url(r'^login$', views.UserLoginAPIView.as_view()),
]
複製程式碼
11. 開始執行專案
python managey makemigrations
python manage.py migrate
python manage.py runserver 192.168.38.127:8000
複製程式碼
192.168.38.127:8000是我電腦自己的WiFiIP,當你手機和你電腦同一WiFi就可以連線專案進行測試
ios-swift部分
1. 網路庫Alamofire
圖片上傳UploadManage.swift
import Foundation
import Alamofire
func getUserHeadImageName()->String{
guard let my = UserInfoModel.getUserInforModel() else {
MBProgressHUD.showError("請先登入")
return ""
}
let user_id = String(describing: my.user_id!)
let date = Date()
let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let strNowTime:String = timeFormatter.string(from: date)
return user_id + "_head_image" + strNowTime + ".jpg"
}
//上傳圖片到伺服器
func uploadImage(imageData : Data,filename:String,url:String,blcok: @escaping ([String: Any]?) -> Void){
MBProgressHUD.showLoading("上傳中...")
let uploadURL = BaseURL + url
guard let my = UserInfoModel.getUserInforModel() else {
blcok(nil)
MBProgressHUD.showError("請先登入")
return
}
let user_id = String(describing: my.user_id!)
Alamofire.upload(
multipartFormData: { multipartFormData in
//採用post表單上傳
//withName:和後臺伺服器的name要一致
multipartFormData.append(imageData, withName: "image", fileName: filename, mimeType: "image/jpeg")
multipartFormData.append(user_id.data(using: String.Encoding.utf8)!, withName: "user_id")
},to: uploadURL,encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
guard let result = response.result.value else {
blcok(nil)
MBProgressHUD.showError("上傳失敗")
return
}
print("json:\(result)")
guard let dict = result as? [String: Any] else {
blcok(nil)
MBProgressHUD.showError("上傳失敗")
return
}
guard let image = dict["result"] as? [String: Any] else{
blcok(nil)
MBProgressHUD.showError("上傳失敗")
return
}
MBProgressHUD.showSuccess("上傳成功")
blcok(image)
}
upload.uploadProgress(queue: DispatchQueue.global(qos: .utility)) { progress in
print("圖片上傳進度: \(progress.fractionCompleted)")
}
case .failure(let encodingError):
MBProgressHUD.showError(encodingError as! String)
blcok(nil)
return
}
})
}
複製程式碼
頭像上傳介面ChangHeadImageViewController.swift
import UIKit
import Photos
class ChangHeadImageViewController: UIViewController {
let imgv = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
self.title = "頭像"
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "編輯", style: .done, target: self, action: #selector(edit))
initUI()
}
func initUI()
{
imgv.frame = self.view.bounds
self.view.addSubview(imgv)
let user = UserInfoModel.getUserInforModel()
imgv.contentMode = .top
imgv.mb_setImage(withUrlString: user?.img, placeholderImgName: "Ico_MCustomerCenter")
}
func edit()
{
let alertSheet = UIAlertController(title: "頭像編輯", message: nil, preferredStyle: .actionSheet)
let phoneAction = UIAlertAction(title: "相簿", style: .default, handler: {action in
self.fromAlbum(type:.photoLibrary)
})
let camerAction = UIAlertAction(title: "相機", style: .default, handler: { action in
self.fromAlbum(type:.camera)
})
let archiveAction = UIAlertAction(title: "完成", style: .destructive, handler: {
action in
print(action)
})
alertSheet.addAction(phoneAction)
alertSheet.addAction(camerAction)
alertSheet.addAction(archiveAction)
self.present(alertSheet, animated: true, completion: nil)
}
//選取相簿
func fromAlbum(type:UIImagePickerControllerSourceType) {
let photos = PHPhotoLibrary.authorizationStatus()
if photos == .notDetermined {
PHPhotoLibrary.requestAuthorization({status in
if status != .authorized{
MBProgressHUD.showError("請在設定裡設定許可權")
return
}
})
}
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
picker.modalPresentationStyle = .overFullScreen
if type == .photoLibrary
{
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary){
picker.sourceType = UIImagePickerControllerSourceType.photoLibrary
self.present(picker, animated: true, completion: {
() -> Void in
})
}else{
MBProgressHUD.showError("沒有相簿許可權")
}
}
else
{
if UIImagePickerController.isSourceTypeAvailable(.camera){
picker.sourceType = UIImagePickerControllerSourceType.camera
self.present(picker, animated: true, completion: {
() -> Void in
})
}else
{
MBProgressHUD.showError("沒有相機許可權")
}
}
}
}
extension ChangHeadImageViewController:UIImagePickerControllerDelegate,UINavigationControllerDelegate
{
@objc func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion:nil)
}
@objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let imageSelected = info[UIImagePickerControllerEditedImage] as? UIImage
picker.dismiss(animated: true, completion:nil)
if imageSelected != nil {
let data = UIImageJPEGRepresentation(imageSelected!, 0.3)
uploadImage(imageData: data!, filename:getUserHeadImageName(), url: "/haveFun/upload_head_image",blcok: { ( dict) in
guard let image = dict!["image"] as? String else{return}
let user = UserInfoModel.getUserInforModel()
user?.img = image
UserInfoModel.saveUserInforModel(user!)
self.imgv.mb_setImage(withUrlString:user?.img, placeholderImgName: "Ico_MCustomerCenter")
} )
}
}
}
複製程式碼