Как в 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)

Таким образом, вы исключаете не пользовательские документы на уровне БД, что гораздо быстрее, чем перебирать каждый документ и проверять, совпадает ли пользователь с пользователем запроса

Вернуться на верх