#django #django-rest-framework
#django #django-rest-framework
Вопрос:
При отправке запроса post изображения сохраняются в media/user_None/pic/1602746423.311224_profile.png вместо media/user_{id}/pic/1602746423.311224_profile.png
Модель учителя
class Teacher(AbstractUser):
profile_pic = models.ImageField(verbose_name="Profile Picture",blank=True,null=True,upload_to=file_pic,default='default.png')
middle_name = models.CharField(max_length=30, blank=True, null=True)
dob = models.DateField(verbose_name='Date Of Birth', null=True)
doj = models.DateField(verbose_name='Date Of Join', null=True)
mobile_num = models.CharField(verbose_name='Mobile Number',max_length=10,null=True,blank=True)
SEX_CHOICE = (
('m','Male'),
('f','Female'),
('t','Transgender'),
('o','Others')
)
sex = models.CharField(max_length=1,choices=SEX_CHOICE,default='m')
department = models.ForeignKey('Department',on_delete=models.SET_NULL,null=True)
функция file_pic для ImageField для сохранения фотографий в папке пользователя на основе его идентификатора
def file_pic(instance, filename):
return 'user_{0}/pic/{2}_{1}'.format(instance.id, filename, time.time())
Сериализатор для создания учителя
class TeacherCreateSerializer(ModelSerializer):
password2 = CharField(write_only=True, style={'input_type':'password'})
class Meta:
model = Teacher
fields = [
'username',
'email',
'mobile_num',
'first_name',
'middle_name',
'last_name',
'dob',
'doj',
'sex',
'department',
'profile_pic',
'password',
'password2'
]
extra_kwargs = {
'password' : {'write_only':True, 'style':{'input_type':'password'}}
}
def create(self,validated_data):
vd_cpy = validated_data
password1 = vd_cpy['password']
password2 = vd_cpy['password2']
vd_cpy.pop('password2')
vd_cpy.pop('password')
teacher = Teacher(**vd_cpy)
if(password1!=password2):
raise ValidationError('password doesn't match')
teacher.set_password(password1)
teacher.save()
return validated_data
def validate_mobile_num(self,value):
value = self.initial_data.get('mobile_num',None)
if value is None or len(value) == 0:
return None
if(re.search(r'^(( ?91|0)?){1}[1-9]{1}[0-9]{9}$',value) is None):
raise ValidationError('Invalid Mobile Number')
return value
def validate_email(self,value):
if(Teacher.objects.filter(email=value).exists()):
raise ValidationError('email already registered')
return value
APIView для создания учителя
class TeacherCreateAPIView(CreateAPIView):
queryset = Teacher.objects.all()
serializer_class = TeacherCreateSerializer
permission_classes = [AllowAny]
parser_classes = (JSONParser,FormParser,MultiPartParser)
Что DRF API Explorer показывает сразу после регистрации
HTTP 201 Created
Allow: POST, OPTIONS
Content-Type: application/json
Vary: Accept
{
"username": "ramverma",
"email": "ram@gmail.com",
"mobile_num": null,
"first_name": "Ram",
"middle_name": "",
"last_name": "Verma",
"dob": null,
"doj": null,
"sex": "m",
"department": 6,
"profile_pic": http://localhost:8000/media/user_None/pic/1602764174.8516657_ProfiePic.png
}
**1st Issue**
** profile_pic сохраняется в папке user_none, но вместо этого он должен быть сохранен в user_{user.id } как написано в функции file_pic. Идея состоит в том, чтобы сохранить все, что связано с пользователем, в одной папке.
{
"profile_pic": "http://localhost:8000/media/user_None/pic/1602764174.8516657_ProfiePic.png",
"first_name": "Ram",
"last_name": "Verma",
"username": "ramverma",
"url": "http://localhost:8000/api/teacher/23"
}
2-я проблема
Если в POST-запросе не указано изображение профиля, то значение profile_pic устанавливается равным null вместо значения по умолчанию, которое указано в ImageFiled в модели
обе проблемы возникают при взаимодействии с API, при веб-взаимодействии проблема не сохраняется
Ответ №1:
Если вы хотите получить доступ к идентификатору объекта, вы должны сначала сохранить () его, поскольку значение вычисляется базой данных, а не django, и нет способа узнать это раньше. Затем вы можете обновить ImageField, вызвав сигнал post_save.
Я не уверен в проблеме с изображением по умолчанию.