Загрузить файл при наличии отношений "один к одному" в django

Простите за весь приведенный код, но я так старался в течение дня, и все равно в итоге возникла проблема при передаче stage_id в качестве параметра в url действия формы

У меня есть класс Rapports, который хранит файл (я предпочитаю pdf файлы) и имеет отношения 1to1 с другим классом из другого приложения, я отправляю stage.id с html страницы в приложении Stages и это работает, id передается и я могу передать его на другую html страницу, но когда я пишу код, который мне нужен и передаю тот же шаблон url в атрибуте action шаблона, который я хочу показать (rapport/test.html ниже), он возвращает NoReverseMatch и я не могу понять почему. Это потому что я пытаюсь загрузить файл или это что-то другое? (первый раз работаю с файлами)

{% block rpt %}
    <li class="nav-item">
        <a class="nav-link" href="{% url 'rapport:depo' stages.id %}">
            déposer le rapport
        </a>
    </li>
{% endblock rpt %}

rapport.Rapports

from django.db import models

from satges.models import Stages

class Rapports(models.Model):
    stage=models.OneToOneField(
        Stages,
        on_delete=models.CASCADE,
        primary_key=True,
    )
    src=models.FileField(
        ("rapport"),
        upload_to='rapports/',
        max_length=100
    )
    r_soummit=models.DateTimeField(
        auto_now=False,
        auto_now_add=False,
    )

satges.Stages

class Stages(models.Model):
    #Stages attrs that are saved so i think no need to show them here

    def est_ete(self):
        # comment: this fn returns true if it's a summer intership
        if(self.deb.month in[6,7,8]):
            return True
    # end def
    def get_absolute_url(self):
        return reverse("satges:det_stg", kwargs={"pk": self.pk})
#saving Stages to database with CreateView is working
    def __str__(self):
        return self.etd + ' ' + self.nature + " - " + self.au

rapport.forms.py

from django import forms

from .models import Rapports

class RapportsForm(forms.ModelForm):
    class Meta:
        model = Rapports
        fields = ['src']
        
        widgets = {
            'src': forms.FileInput(),
        }

rapport.views

from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
from django.views.generic import CreateView
from satges.models import Stages
from .models import Rapports
from .forms import RapportsForm

# Create your views here.

def afficher(request, stage_id):
    # comment: 
    #return HttpResponse('stage: %s'% stage_id)
    if request.method == 'POST':
        form = RapportsForm(request.POST, request.FILES)
    else:
        form=RapportsForm()
    return render(request, 'rapport/test.html', {'form': form})

class RapportCreateView(CreateView):
    model = Rapports
    form_class=RapportsForm
    template_name = "rapport/test.html"


# end def
'''
def afficher_depo(request, stage_id):
    form=RapportsForm()
    print(stage_id)
    return render(request,'rapport/depo.html', {'form': form})

def depo(request, stage_id):
    if request.method == 'POST':
        form = RapportsForm(request.POST)
        stage=get_object_or_404(Stages, pk=stage_id)
        src = form.cleaned_data['src']
        rpt=Rapports(stage=stage,src=src)
        rpt.save()
    else:
        return HttpResponse('rapport isn\'t saved')
    
    return render(request,'rapport/depo.html', {'form':form})
    '''

урл проекта conf

from django.contrib import admin
from django.urls import include, path
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('satges.urls')),
    path('journal/', include('journaux.urls')),
    path('rapport/<int:pk>', include('rapport.urls')),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

rapport.urls.py

from django.urls import path, re_path
from . import views

app_name = 'rapport'
urlpatterns = [
    path('',views.RapportCreateView.as_view(), name='depo'),
]

test.html (этот файл просто для тестирования, основной файл называется depo.html и он расширяет страницу и имеет такое же поведение, когда я удаляю url в действии, появляется форма)

<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <form method="post" enctype="multipart/form-data" action="{% url 'rapport:depo' satge_id %}">
      <!--when i remove the url tag the input form appears and i can choose a file but i ofc can't send it without the action-->
        {% csrf_token %}
        {{ form.as_p }}
    <input type="submit" value="déposer votre rapport" name="depo">
    </form>
  </body>
</html>

здесь должен быть весь код, связанный с проблемой, я пробовал гуглить, ютуб, django doc и с изменениями, которые я делал в течение дня, ошибки отличались, но та, которую я не смог пройти - NoReverseMatch

error

Error during template rendering

In template /home/ssoya/Documents/pfe/new/pages/templates/rapport/test.html, error at line 6
Reverse for 'depo' with arguments '('',)' not found. 1 pattern(s) tried: ['rapport/(?P<pk>[0-9]+)\\Z']

я готов переформулировать вопрос, как только найду решение или пойму его больше

это из-за stage_id, так как он не определен, поэтому url не будет найден, так как ему нужен параметр stage_id, проверьте представление, которое рендерит ваш шаблон, оно не возвращает переменную stage_id
. добавьте это в ваше представление создания

def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super().get_context_data(**kwargs)
        # context is a dict so 
        #update it with your stage id
        return context

в этой функции добавьте stage_id, чтобы он был передан в шаблон

я могу сказать, что она на 90% решена

проблема, с которой я столкнулся в этом вопросе, была связана с контекстом в моем представлении, и после ответа @mohamed и некоторых гуглений и попыток я сделал представление, в итоге оно заработало и сохранило файл на сервер и в базу данных и поместило id объекта Satges как id раппорта как атрибут satge_id затем перенаправляет пользователя на другую страницу

вот изменения, которые я сделал

views.py

class RapportsCreateView(CreateView):
    model = Rapports
    form_class = RapportsForm
    template_name = "rapport/depo.html"

    def form_valid(self, form):
        self.stage_id = self.kwargs['pk']
        stage = Stages.objects.get(id=self.stage_id)
        form.instance.stage_id = stage.id
        form.instance.r_soummit = timezone.now()
        return super().form_valid(form)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        stage = Stages.objects.get(pk=self.kwargs.get('pk'))
        context['stage'] = stage
        context['stage_id'] = stage.id
        return context

models.Rapports

def get_absolute_url(self):
        return reverse("rapport:det_rpt", kwargs={"pk": self.pk})

def __str__(self):
        return self.src
Вернуться на верх