Как в django показать документы, загруженные только определенными пользователями?
Я новичок в django и пытаюсь создать пользовательскую систему, в которой разные пользователи могут входить в систему, загружать и просматривать свои документы. Загрузка и просмотр работают, но пользователи могут видеть и документы друг друга. Как я могу сделать так, чтобы пользователи могли видеть только документы, загруженные ими?
В следующем вопросе также говорится о той же проблеме, но я не могу понять, как она была решена: Как показать блог пользователя на странице профиля пользователя как раздел списка моих сообщений в Django 3?
Я понимаю, что мне нужно использовать внешние ключи в моих моделях, но я не уверен, как это реализовать. Вот фрагменты моего кода на данный момент:
Модель документа для загрузки с внешним ключом пользователя
class Document(models.Model):
user = models.ForeignKey(User, default = 1, null = True, on_delete = models.SET_NULL)
docfile = models.FileField(upload_to='documents/%Y/%m/%d')
Модель пользователя
class User(models.Model):
name = models.CharField(max_length=255)
author = models.ForeignKey(User, default = 1, null = True, on_delete = models.SET_NULL)
id = models.IntegerField(primary_key=True)
email = models.EmailField(max_length=500, unique=True)
username = models.CharField(max_length=255, unique=True)
password = models.CharField(max_length=255)
функция документа в views.py
def my_view(request):
print(f"Great! You're using Python 3.6+. If you fail here, use the right version.")
message = 'Upload as many files as you want!'
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile=request.FILES['docfile'])
newdoc.user = request.user;
newdoc.save()
# Redirect to the document list after POST
return redirect('my-view')
else:
message = 'The form is not valid. Fix the following error:'
else:
form = DocumentForm() # An empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
context = {'documents': documents, 'form': form, 'message': message}
return render(request, 'list.html', context)
html код для документов. Я точно знаю, что этот код предназначен для показа всех документов в базе данных и ничего не делает для фильтрации документов, но все мои попытки изменить это приводят к ошибкам, поэтому это единственная рабочая версия.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Minimal Django File Upload Example</title>
</head>
<body>
<!-- List of uploaded documents -->
{% if documents %}
All documents in the database:
<ul>
{% for document in documents %}
<li><a href="{{ document.docfile.url }}">{{ document.docfile.name }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No documents.</p>
{% endif %}
<!-- Upload form. Note enctype attribute! -->
<form action="{% url "my-view" %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ message }}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<p><input type="submit" value="Upload"/></p>
</form>
<div>To go back home, <a href="{% url 'authApp:home' %}">Click Here</a></div>
</body>
</html>
Просто добавьте условие внутри цикла:
{% for document in documents %}
{% if document.user == request.user %}
<li><a href="{{ document.docfile.url }}">{{ document.docfile.name }}</a></li>
{% endif %}
{% endfor %}
С этим каждый User
может видеть только Document
объекты, которые заданы ему в ForeignKey
поле user
.
Если вы хотите отобразить пользователю только документы, созданные пользователем запроса, вы можете отфильтровать ваш набор запросов Document по внешнему ключу пользователя:
# Load documents for the list page
documents = Document.objects.filter(user=request.user)
# Render list page with the documents and the form
context = {'documents': documents, 'form': form, 'message': message}
return render(request, 'list.html', context)
Таким образом, вы исключаете не пользовательские документы на уровне БД, что гораздо быстрее, чем перебирать каждый документ и проверять, совпадает ли пользователь с пользователем запроса