Home > OS >  Django - Can't get the specific primary key (id) for an object in a list of objects
Django - Can't get the specific primary key (id) for an object in a list of objects

Time:03-27

I am trying to get the specific pk of the selected object when the user accepts a delivery. My problem is that I'm getting only the first object's pk in the list every time. I want to get the pk of the selected object.

views:

@login_required(login_url="/signin/?next=/driver/")
def deliveries_available_page(request):

    deliveries = Delivery.objects.filter(
        status_of_delivery__in=[Delivery.DELIVERY_POSTED]
    )
    
    #When driver accept delivery then status of delivery changes to delivering
    if request.method == 'POST':
        delivery = get_object_or_404(Delivery, pk=request.POST.get('receipt_number'))
        if delivery:
            delivery.status_of_delivery = Delivery.DELIVERY_DELIVERING
            delivery.driver = request.user.driver
            messages.success(request, 'Delivery Accepted')
            delivery.save()
    
        return redirect(reverse('driver:deliveries_available'))
    return render(request, 'driver/deliveries_available.html', {
        "GOOGLE_API_MAP": settings.GOOGLE_API_MAP,
        "del": deliveries
    })

HTML:

<div  style="padding-bottom: 50px">
    <div id="map"></div>
    {% if del %}
    {% for d in del %}
    <div  id="delivery-popup">
        <div >
            <div >
                <div >
                    <strong id="address"></strong>
                    <div>
                        <strong id="show-info"></strong>
                    </div>
                    <div>
                        <strong id="show-distance"></strong>
                        <strong id="show-duration"></strong>
                    </div>
                    <div>
                        <strong id="show-price"></strong>
                        <strong id="show-id"></strong>
                    </div>


                    <div>
                        <form method="POST">
                            {% csrf_token %}
                            <button type="submit"         name="accept">Accept</button>
                            <input type="hidden" value="{{ d.receipt_number }}" name="receipt_number">
                        </form>
                    </div>
                    
  
                    {% if messages %}
                    {% for m in messages %}
                    {% if m.tags %}
                    <script>alert("{{ m }}")</script>
                    {% endif %}
                    {% endfor %}
                    {% endif %}
                </div>
            </div>
        </div>
    </div>
    {% endfor %}
    {% endif %}

When i click on the address the pk stays the same

I need the specific pk so when user accept delivery, then the right delivery is accepted and removed from the map. Any help would be appreciated. Thanks.

I can get the specific pk by creating new url and passing it in the url but i want user to accept delivery on the map page.

script added to html

<script>
//Google map and using api to display deliveries on map and click event to show delivery details
function initMap() {
    const map = new google.maps.Map(document.getElementById("map"), {
        center: { lat: 53.350140, lng: -6.266155 },
        zoom: 13,
    });

    fetch("{% url 'driver:available_deliveries' %}").then(response => response.json()).then(json => {
        console.log(json);

        for (let d = 0; d < json.deliveries.length; d  ) {
            const delivery = json.deliveries[d];
            const position = { lat: delivery.delivery_address_latitude, lng: delivery.delivery_address_longitude };
            const show_on_map = new google.maps.Marker
                ({
                    position,
                    map,
                });

            new google.maps.InfoWindow({
                content: "<small><strong>"   delivery.address   "<medium><br>€"   delivery.price
            }).open(map, show_on_map);

            show_on_map.addListener("click", () => {
                PopUpDelivery(delivery);
            })
        }
    })
}

function PopUpDelivery(delivery) {
    $("#delivery-popup").css("display", "block");
    $("#address").html(delivery.address);
    $("#show-distance").html(delivery.distance   " Km");
    $("#show-duration").html(delivery.duration   " Mins");
    $("#show-price").html("€ "   delivery.price);
    $("#show-info").html("Info : "   delivery.information);
    $("#show-id").html("Pk : "   delivery.receipt_number)
}

CodePudding user response:

Solved:

Got the specific pk, when i click on a delivery it gets the right pk, code below if anyone has the same problem:

script

function PopUpDelivery(delivery) {
    $("#delivery-popup").css("display", "block");
    $("#address").html(delivery.address);
    $("#show-distance").html(delivery.distance   " Km");
    $("#show-duration").html(delivery.duration   " Mins");
    $("#show-price").html("€ "   delivery.price);
    $("#show-info").html("Info : "   delivery.information);
    $("#show-id").html("Pk : "   delivery.receipt_number);
    
    var input_tag = getTag('getpk');
    input_tag.value = delivery.receipt_number;
}
function getTag(id){
    return document.getElementById(id);
}

html

<button type="submit"  name="accept">Accept</button>
                        <input type="hidden" id="getpk" value="" name="receipt_number">

CodePudding user response:

Keep id unique in html document

The id in an HTML document must be unique within each page source:

The id global attribute defines an identifier (ID) which must be unique in the whole document. Its purpose is to identify the element when linking (using a fragment identifier), scripting, or styling (with CSS).

What I think may have occurred is that since you have many cards in each page, all with the same id's, you were just getting the first one. While your solution works, I think it might be better to give each id a unique value, which you can do simply by appending the pk, or any unique field to the id names. With this, you may not need the function getTag. Here is what I mean:

html

<div  style="padding-bottom: 50px">
    <div id="map"></div>
    {% if del %}
    {% for d in del %}
    <div  id="delivery-popup">
        <div >
            <div >
                <div >
                    <strong id="address{{ d.pk }}"></strong>
                    <div>
                        <strong id="show-info{{ d.pk }}"></strong>
                    </div>
                    <div>
                        <strong id="show-distance{{ d.pk }}"></strong>
                        <strong id="show-duration{{ d.pk }}"></strong>
                    </div>
                    <div>
                        <strong id="show-price{{ d.pk }}"></strong>
                        <strong id="show-id{{ d.pk }}"></strong>
                    </div>


                    <div>
                        <form method="POST">
                            {% csrf_token %}
                            <button type="submit"         name="accept">Accept</button>
                            <input type="hidden" value="{{ d.receipt_number }}" name="receipt_number">
                        </form>
                    </div>
                    
  
                    {% if messages %}
                    {% for m in messages %}
                    {% if m.tags %}
                    <script>alert("{{ m }}")</script>
                    {% endif %}
                    {% endfor %}
                    {% endif %}
                </div>
            </div>
        </div>
    </div>
    {% endfor %}
    {% endif %}

script

<script>
//Google map and using api to display deliveries on map and click event to show delivery details
function initMap() {
    const map = new google.maps.Map(document.getElementById("map"), {
        center: { lat: 53.350140, lng: -6.266155 },
        zoom: 13,
    });

    fetch("{% url 'driver:available_deliveries' %}").then(response => response.json()).then(json => {
        console.log(json);

        for (let d = 0; d < json.deliveries.length; d  ) {
            const delivery = json.deliveries[d];
            const position = { lat: delivery.delivery_address_latitude, lng: delivery.delivery_address_longitude };
            const show_on_map = new google.maps.Marker
                ({
                    position,
                    map,
                });

            new google.maps.InfoWindow({
                content: "<small><strong>"   delivery.address   "<medium><br>€"   delivery.price
            }).open(map, show_on_map);

            show_on_map.addListener("click", () => {
                PopUpDelivery(delivery);
            })
        }
    })
}

function PopUpDelivery(delivery) {
    let pk = delivery.pk
    $("#delivery-popup" pk).css("display", "block");
    $("#address" pk).html(delivery.address);
    $("#show-distance" pk).html(delivery.distance   " Km");
    $("#show-duration" pk).html(delivery.duration   " Mins");
    $("#show-price" pk).html("€ "   delivery.price);
    $("#show-info" pk).html("Info : "   delivery.information);
    $("#show-id" pk).html("Pk : "   delivery.receipt_number)
}
  • Related