I created a view that add stops to route and they are not appearing by parameter order from models

Viewed 19

I created view where i add stops to route, its working fine, but stops are not appearing in order when i add them, and i have no idea why. Please tell me where i'm making a mistake

Here's my code:

Models:

class Port(models.Model):
    name = models.CharField(max_length=128)
    description = models.TextField(default='')
    lattitude = models.DecimalField(max_digits=9, decimal_places=6)
    longitude = models.DecimalField(max_digits=9, decimal_places=6)
    amenities = models.ManyToManyField(Amenity, blank=True)

    def __str__(self):
        return f'{self.name}'

class Route(models.Model):
    name = models.CharField(max_length=128, default='')
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    stop_list = models.ManyToManyField(Port, through='RoutePort')

    def __str__(self):
        return f'{self.name}'



class RoutePort(models.Model):
    port = models.ForeignKey(Port, on_delete=models.CASCADE)
    route = models.ForeignKey(Route, on_delete=models.CASCADE)
    order = models.PositiveIntegerField()

    class Meta:
        ordering = ['order']

the order i intend them to appear is set by 'order' parameter from class routeport

form:

class AddRoutePort(forms.ModelForm):

    class Meta:
        model = RoutePort
        fields = ['port', 'order']

form is short and i dont know if i didnt forget something there

View, get is working correctly, post works almost ok. New ports are correctly added to new route from list, but they appear in order of being added, not the one i wanted them to.

class RouteCorrectView(View):

    def get(self, request, pk):
        route = Route.objects.get(pk=pk)
        form = AddRoutePort()
        return render(request, 'route_correct.html', {'route':route, 'form':form})


    def post(self, request, pk):
        route = Route.objects.get(pk=pk)
        form = AddRoutePort(request.POST)
        if form.is_valid():
            to_port = form.save(commit=False)
            to_port.route = route
            order = to_port.order
            ordering = RoutePort.objects.filter(order__gte=order, route=route)
            for port in ordering:
                port.order += 1
                port.save()
            to_port.save()
            return redirect('route_correct', pk)
        return render(request, 'route_correct.html', {'route':route, 'form':form})

and HTML - i can't draw set order here, so i think theres a mistake somwhere previously. Line {{ stops.order }} does nothing.

{% extends 'base.html' %}
{% block content %}
    <div class="card">
    <ul>Nazwa</ul>
        <p>{{ route.name }}</p>
    <ul>Twórca</ul>
        <p> {{ route.user }}</p>
    <ul>Szlak</ul>
        <td> {% for stops in route.stop_list.all %}
        {{ stops }} {{ stops.order }}
            <td>
            <form action="{% url 'delete_stop' stops.id %}" method="get"> {% csrf_token %}
                <input type="submit">usuń</form>
            <form action="{% url 'port_detail' stops.id %}" method="get"> {% csrf_token %}
                <input type="submit">o porcie</form><br>
        </td>
            {% empty %}
            Szlak jest jeszcze pusty
        {% endfor %}</td>
    </div>

    <form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit">
</form>



    </div>

{% endblock %}

1 Answers

So i found the solution. First of all i'm an idiot, second of all - html was problem

<td> {% for stops in route.stop_list.all %}
    {{ stops }} {{ stops.order }}
        <td>

Above part refer to stop list, not routeport model with "order" in it. It should look like that:

<td> {% for stops in route.routeport_set.all %}
    {{ stops.port }}  {{ stops.order }}
        <td>
        

where i refer to routeport with order in it.

Related