#python #django #authentication #permissions
#python #django #аутентификация #разрешения
Вопрос:
У меня есть модель «document», система загрузки, использующая dropzone.js и регистрация / вход в систему. Теперь я не понимаю, как применять разрешения к каждому отдельному загруженному файлу, чтобы только указанные пользователи могли получить к ним доступ.
В основном: File1-> accessible_by = user1, user2
File2-> accesible_by= user3, user5…
И так далее.
Спасибо всем за советы / помощь по моей проблеме.
Редактировать с помощью соответствующего кода:
Создать представление документа:
class DocumentCreate(CreateView):
model = Document
fields = ['file', 'is_public']
def form_valid(self, form):
self.object = form.save()
data = {'status': 'success'}
response = JSONResponse(data, mimetype =
response_mimetype(self.request))
return response
Я сделал выше для представления для обработки dropzone.js загрузка файлов.
Это моя модель «документа»
class Document(models.Model):
file = models.FileField(upload_to = 'files/')
#validators=[validate_file_type])
uploaded_at = models.DateTimeField(auto_now_add = True)
extension = models.CharField(max_length = 30, blank = True)
thumbnail = models.ImageField(blank = True, null = True)
is_public = models.BooleanField(default = False)
uploaded_by = models.ForeignKey(User,
related_name='uploadedByAsUser', null=True)
allowed_users = models.ManyToManyField(User,
related_name='allowedUsersAsUser')
def clean(self):
self.file.seek(0)
self.extension = self.file.name.split('/')[-1].split('.')[-1]
if self.extension == 'xlsx' or self.extension == 'xls':
self.thumbnail = 'xlsx.png'
elif self.extension == 'pptx' or self.extension == 'ppt':
self.thumbnail = 'pptx.png'
elif self.extension == 'docx' or self.extension == 'doc':
self.thumbnail = 'docx.png'
def delete(self, *args, **kwargs):
#delete file from /media/files
self.file.delete(save = False)
#call parent delete method.
super().delete(*args, **kwargs)
#Redirect to file list page.
def get_absolute_url(self):
return reverse('dashby-files:files')
def __str__(self):
return self.file.name.split('/')[-1]
class Meta():
ordering = ['-uploaded_at']
Ответ №1:
Вы можете добавить allowed_user
поле в модель документа, чтобы только указанные пользователи могли получить доступ к файлам. например:
class Document(models.Model):
file = FileField()
uploaded_by = models.ForeignKey(User, related_name='uploadedByAsUser')
allowed_users = models.ManyToManyField(User, related_name='allowedUsersAsUser')
Таким образом, если вы хотите, чтобы пользователь был добавлен в список «разрешенных», вы можете просто добавить их, используя что-то вроде этого:
class DocumentCreate(CreateView):
model = Document
fields = ['file', 'is_public']
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.allowed_users.add(request.user)
self.object.save()
data = {'status': 'success'}
response = JSONResponse(data, mimetype =
response_mimetype(self.request))
return response
Затем, чтобы администратор выглядел красиво (admin.py ):
class DocumentAdmin(admin.ModelAdmin):
list_display = ('uploaded_by', 'file')
fields = ('id', 'file', 'uploaded_at', 'extension', 'thumbnail', 'is_public', 'uploaded_by', 'allowed_users')
filter_horizontal = ('allowed_users',)
readonly_fields = ('id',)
admin.site.register(Document, DocumentAdmin)
Затем, если вы хотите проверить, разрешены ли они, вы можете сделать:
if allowed_user in doc.allowed_users:
print('We have liftoff')
Комментарии:
1. Я пытался использовать ManyToManyField, но всякий раз, когда я загружал файл, каждая учетная запись пользователя, созданная в базе данных, автоматически добавлялась в allowed_users без моих действий, а также я не мог получить доступ к фактическим данным и изменить их.
2. Кроме того, при добавлении uploaded_by и allowed_users в модель я получаю сообщение об ошибке, в котором говорится, что у меня не может быть 2 полей с одним и тем же связанным объектом.
3. Я добавил
related_name
поле, чтобы исправить ошибку, указанную в вашем втором комментарии, что касается вашего первого комментария, пожалуйста, будьте немного конкретнее. Можете ли вы показать мне код представления? Может быть, вы случайно перебираете всех пользователей и добавляете их вallowed_users
?4. Да, извините, я думаю, я слишком расплывчатый. Я обновил сообщение соответствующим кодом. Спасибо за первое исправление, не знал о связанном имени. Может быть, это делает CreateView, от которого я наследую? не совсем уверен.
5. Хорошо, отлично, теперь вопрос: итак, вы говорите, что когда вы просматриваете
DocumentCreate
представление,allowed_users
оно заполняется ВСЕМИ пользователями в базе данных?
Ответ №2:
Вы можете установить content_type для HttpResponse. Таким образом, вы можете выполнять обработку разрешений в своем представлении и обслуживать файл непосредственно из Django:
return HttpResponse("Text only, please.", content_type="text/plain")
Примечание: Django не является веб-сервером. Рекомендуется использовать веб-сервер для обслуживания статических файлов!
Приведенный выше метод может быть хорошим подходом, если вы обрабатываете небольшие объемы данных и только случайно обрабатываете данные. Если вам нужно надежное решение, вам нужно проверить разрешения в Django и оставить отправку данных на веб-сервер.
- Lighthttpd X-Sendfile
- Внутренние перенаправления Apache mod_wsgi
- NGNIX X-Ускорение-перенаправление
Взгляните на пакеты потоковой передачи файлов Django: https://djangopackages.org/grids/g/file-streaming /
Комментарии:
1. Я использую Apache с mod_wsgi, но я не знаю, обслуживаю ли я файлы через Apache или Django, что довольно ново для серверной части и веб-разработчиков в целом. На самом деле мне нужно постоянно загружать файлы, поэтому мне было бы интересно использовать Apache для обслуживания файлов и использовать разрешения django, но я не могу понять это прямо сейчас. Как мне поступить?
2. Итак, небольшая поправка. Я уже обслуживаю статические файлы через Apache, поэтому хотел бы знать, как поступить с разрешениями django, спасибо 🙂