| @@ -2,7 +2,7 @@ | ||
| 2 | 2 |  | 
| 3 | 3 | from django.contrib import admin | 
| 4 | 4 |  | 
| 5 | -from photo.models import PhotosInfo, UUIDInfo | |
| 5 | +from photo.models import PhotosInfo, PhotoUUIDInfo, UUIDInfo | |
| 6 | 6 |  | 
| 7 | 7 |  | 
| 8 | 8 | class UUIDInfoAdmin(admin.ModelAdmin): | 
| @@ -10,6 +10,11 @@ class UUIDInfoAdmin(admin.ModelAdmin): | ||
| 10 | 10 |      list_filter = ('lensman_id', 'status') | 
| 11 | 11 |  | 
| 12 | 12 |  | 
| 13 | +class PhotoUUIDInfoAdmin(admin.ModelAdmin): | |
| 14 | +    list_display = ('photo_md5', 'photo_path', 'status', 'created_at', 'updated_at') | |
| 15 | +    list_filter = ('status', ) | |
| 16 | + | |
| 17 | + | |
| 13 | 18 | class PhotosInfoAdmin(admin.ModelAdmin): | 
| 14 | 19 |      list_display = ('lensman_id', 'session_id', 'photo_id', 'p_photo_path', 'm_photo_path', 'l_photo_path', 'r_photo_path', 'status', 'created_at', 'updated_at') | 
| 15 | 20 |      list_filter = ('lensman_id', 'status') | 
| @@ -17,3 +22,4 @@ class PhotosInfoAdmin(admin.ModelAdmin): | ||
| 17 | 22 |  | 
| 18 | 23 | admin.site.register(UUIDInfo, UUIDInfoAdmin) | 
| 19 | 24 | admin.site.register(PhotosInfo, PhotosInfoAdmin) | 
| 25 | +admin.site.register(PhotoUUIDInfo, PhotoUUIDInfoAdmin) | 
| @@ -0,0 +1,29 @@ | ||
| 1 | +# -*- coding: utf-8 -*- | |
| 2 | +from __future__ import unicode_literals | |
| 3 | + | |
| 4 | +from django.db import models, migrations | |
| 5 | + | |
| 6 | + | |
| 7 | +class Migration(migrations.Migration): | |
| 8 | + | |
| 9 | + dependencies = [ | |
| 10 | +        ('photo', '0009_auto_20160907_1018'), | |
| 11 | + ] | |
| 12 | + | |
| 13 | + operations = [ | |
| 14 | + migrations.CreateModel( | |
| 15 | + name='PhotoUUIDInfo', | |
| 16 | + fields=[ | |
| 17 | +                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), | |
| 18 | +                ('status', models.BooleanField(default=True, help_text='\u72b6\u6001', db_index=True, verbose_name='status')), | |
| 19 | +                ('created_at', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', verbose_name='created_at', auto_now_add=True)), | |
| 20 | +                ('updated_at', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', verbose_name='updated_at', auto_now=True)), | |
| 21 | +                ('photo_md5', models.CharField(null=True, max_length=255, blank=True, help_text='\u7167\u7247\u552f\u4e00\u6807\u8bc6', unique=True, verbose_name='photo_md5', db_index=True)), | |
| 22 | +                ('photo_path', models.CharField(help_text='\u7167\u7247\u8def\u5f84', max_length=255, null=True, verbose_name='photo_path', blank=True)), | |
| 23 | + ], | |
| 24 | +            options={ | |
| 25 | + 'verbose_name': 'photouuidinfo', | |
| 26 | + 'verbose_name_plural': 'photouuidinfo', | |
| 27 | + }, | |
| 28 | + ), | |
| 29 | + ] | 
| @@ -27,6 +27,18 @@ class UUIDInfo(CreateUpdateMixin): | ||
| 27 | 27 | } | 
| 28 | 28 |  | 
| 29 | 29 |  | 
| 30 | +class PhotoUUIDInfo(CreateUpdateMixin): | |
| 31 | + photo_md5 = models.CharField(_(u'photo_md5'), max_length=255, blank=True, null=True, help_text=u'照片唯一标识', db_index=True, unique=True) | |
| 32 | + photo_path = models.CharField(_(u'photo_path'), max_length=255, blank=True, null=True, help_text=u'照片路径') | |
| 33 | + | |
| 34 | + class Meta: | |
| 35 | +        verbose_name = _('photouuidinfo') | |
| 36 | +        verbose_name_plural = _('photouuidinfo') | |
| 37 | + | |
| 38 | + def __unicode__(self): | |
| 39 | +        return u'{0.pk}'.format(self) | |
| 40 | + | |
| 41 | + | |
| 30 | 42 | class PhotosInfo(CreateUpdateMixin): | 
| 31 | 43 | lensman_id = models.CharField(_(u'lensman_id'), max_length=255, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True) | 
| 32 | 44 | session_id = models.CharField(_(u'session_id'), max_length=255, blank=True, null=True, help_text=u'照片组唯一标识', db_index=True) | 
| @@ -9,6 +9,7 @@ TimeConvert==1.3.12 | ||
| 9 | 9 | cryptography==1.5.2 | 
| 10 | 10 | django-curtail-uuid==1.0.0 | 
| 11 | 11 | django-detect==1.0.5 | 
| 12 | +django-file-md5==1.0.0 | |
| 12 | 13 | django-ip==1.0.0 | 
| 13 | 14 | django-json-response==1.1.4 | 
| 14 | 15 | django-logit==1.0.6 | 
| @@ -4,12 +4,25 @@ import os | ||
| 4 | 4 |  | 
| 5 | 5 | import shortuuid | 
| 6 | 6 | from django.core.files.storage import default_storage | 
| 7 | +from django.db import transaction | |
| 8 | +from filemd5 import calculate_md5 | |
| 7 | 9 |  | 
| 10 | +from photo.models import PhotoUUIDInfo | |
| 8 | 11 |  | 
| 12 | + | |
| 13 | +@transaction.atomic | |
| 9 | 14 | def file_save(file_, prefix='img', ext='jpeg'): | 
| 10 | 15 | ext = os.path.splitext(file_.name)[-1] or ext | 
| 11 | -    path = '{}/{}{}'.format(prefix, shortuuid.uuid(), ext) | |
| 12 | - if default_storage.exists(path): | |
| 13 | - default_storage.delete(path) | |
| 14 | - default_storage.save(path, file_) | |
| 15 | - return path, ext | |
| 16 | + | |
| 17 | + photo, created = PhotoUUIDInfo.objects.select_for_update().get_or_create(photo_md5=calculate_md5(file_)) | |
| 18 | + | |
| 19 | + if not photo.photo_path: | |
| 20 | +        path = '{}/{}{}'.format(prefix, shortuuid.uuid(), ext) | |
| 21 | + if default_storage.exists(path): | |
| 22 | + default_storage.delete(path) | |
| 23 | + default_storage.save(path, file_) | |
| 24 | + | |
| 25 | + photo.photo_path = path | |
| 26 | + photo.save() | |
| 27 | + | |
| 28 | + return photo.photo_path, ext |