Джанго: Как получить последнюю запись?

#python #django

Вопрос:

Что я хочу сделать , так это то, что для определенного идентификатора цилиндра, если цилиндр выпущен, то имя пользователя и дата выпуска будут отображаться в списке цилиндров, а также, если цилиндр возвращен, то дата возврата будет отображаться в списке цилиндров, поэтому для этого я использовал prefetch_related, и в шаблоне я повторяю проблему и возвращаю модель следующим образом :-

 {%for cy in cylinder %}
                    <tr bgcolor="#e6f0ff" align="center">
                        
                    <td align="center" height="10" 
                width="50"><a style="border-width: 0px" href="{{cy.get_absolute_url}}">{{cy.cylinderId}}<a></td>
               
                    <td align="center" height="10" 
                width="50">{{cy.EntryDate}}</td>
                    <td align="center" height="10" 
                width="50">{{cy.gasName}}</td>
                <td align="center" height="10" 
                width="50">
                    {{cy.cylinderSize}}</td>
                    <td align="center" height="10" 
                width="50">
                    {{cy.Status}}</td>
                    <td align="center" height="10" 
                width="50">{{cy.Availability}}</td>

                {% if cy.issue_set.all%}
                
                {% for issue in cy.issue_set.all %}
                <td align="center" height="10" 
                width="50">{{issue.issueDate}}</td>
                <td align="center" height="10" 
                width="50">{{issue.userName}}</td>
               {% endfor %}
                
                {% else %}
                <td align="center" height="10" 
                width="50">-</td>
                <td align="center" height="10" 
                width="50">-</td>

                {% endif%}

                 {% if cy.return_set.all%}
                
                {% for return in cy.return_set.all %}
                <td align="center" height="10" 
                width="50">{{return.returnDate}}</td>
               
               {% endfor %}
                
                {% else %}
                
                <td align="center" height="10" 
                width="50">-</td>

                {% endif%}
                                
                
                    </tr>

                    {% endfor %}
                </tbody>

            {% else %}
 

Но возникает другая проблема: если я переиздам один и тот же цилиндр/верну снова тот же идентификатор цилиндра, поэтому в таблице списка цилиндров отображаются все записи о проблемах и возврате, созданные для этого идентификатора цилиндра, но вместо этого я просто хочу отобразить последнюю запись о проблемах и возврате, для этого что я должен сделать?

вот мое мнение:-

 def cylinderListView(request):
    cylinder=Cylinder.objects.all().prefetch_related().order_by('-EntryDate')
    
    return render(request,'entry/cylinderList.html',locals())
 

вот модели:-

 from django.db import models
from django.utils import timezone
from django.urls import reverse

# Create your models here.
class Cylinder(models.Model):
    stachoice=[
    ('Fill','fill'),
    ('Empty','empty') 
    ]
    substachoice=[
    ('Available','available'), 
    ('Unavailable','unavailable'),
    ('Issued','issued') 
    
    ]
    cylinderId=models.CharField(max_length=50,primary_key=True,null=False)
    gasName=models.CharField(max_length=200)
    cylinderSize=models.CharField(max_length=30)
    Status=models.CharField(max_length=40,choices=stachoice,default='fill')
    Availability=models.CharField(max_length=40,choices=substachoice,default="Available")
    EntryDate=models.DateTimeField(default=timezone.now)
    
    

    def get_absolute_url(self):
        return reverse('cylinderDetail',args=[(self.cylinderId)])

    def __str__(self):
        return str(self.cylinderId)

class Issue(models.Model):
    cylinder=models.ForeignKey('Cylinder',on_delete=models.CASCADE)
    userName=models.CharField(max_length=60,null=False)
    issueDate=models.DateTimeField(default=timezone.now)
    
    def save(self,*args,**kwargs):
        if not self.pk: 
            if self.cylinder.Availability=='Available':
                Cylinder.objects.filter(cylinderId=self.cylinder.cylinderId).update(Availability=('Issued'))

        super().save(*args,**kwargs)
        
    def __str__(self):
        
        return str(self.userName) 


class Return(models.Model):
    fill=[
    ('Fill','fill'),
    ('Empty','empty'),
    ('refill','Refill')
    ]

    ava=[
    ('yes','YES'),
    ('no','NO')
    ]
    cylinder=models.ForeignKey('Cylinder',on_delete=models.CASCADE)
    availability=models.CharField(max_length=20,choices=ava)
    status=models.CharField(max_length=10,choices=fill)
    returnDate=models.DateTimeField(default=timezone.now)
    def save(self,*args,**kwargs):
        if not self.pk:

            if self.cylinder.Availability=='Issued':
                
                if self.availability=='YES' or self.availability=='yes':
                    Cylinder.objects.filter(cylinderId=self.cylinder.cylinderId).update(Availability='Available')
                    if self.status=='empty' or self.status=='Empty':
                        Cylinder.objects.filter(cylinderId=self.cylinder.cylinderId).update(Status='Empty')
                else:
                    Cylinder.objects.filter(cylinderId=self.cylinder.cylinderId).update(Availability='Unavailable')
                    if self.status=='refill' or self.status=='Refill':
                        Cylinder.objects.filter(cylinderId=self.cylinder.cylinderId).update(Status='Refill')
                    if self.status=='empty' or self.status=='Empty':
                        Cylinder.objects.filter(cylinderId=self.cylinder.cylinderId).update(Status='Empty')


        super().save(*args,**kwargs)

    def __str__(self):
        return str(self.cylinder)
 

тот вид, который я хочу:

введите описание изображения здесь

Комментарии:

1. Почему второй пункт 4 мая, 12:00 для a Cylinder с идентификатором = 100? Это не отображается ни в одной из таблиц.

2. второй элемент цилиндр с идентификатором=100 будет отображаться только в таблице выдачи и таблице возврата соответственно , а не в таблице цилиндров , в таблице цилиндров будут отображаться только последние записи для идентификатора цилиндра=100, т. е. 7 мая, 15:00

3. но каков именно предполагаемый результат? Так Return это не желаемый результат, а другая таблица/модель?

4. Возврат и выдача — это другие модели. Я также редактирую свои модели. Я буду очень благодарен, если вы подскажете мне, как это правильно сделать 🙂

5. можете ли вы указать ожидаемый результат для заданных данных. Мне все еще не совсем ясно, чего вы хотите достичь.

Ответ №1:

Вы можете получить первый для этого набора запросов с помощью .first() метода [Django-doc]:

 def cylinderListView(request):
    cylinder=Cylinder.objects.order_by('-EntryDate').first()
    
    return render(request,'entry/cylinderList.html', {'cylinder': cylinder}) 

или мы можем упорядочить в порядке возрастания и вернуть .last() метод [Django-doc]:

 def cylinderListView(request):
    cylinder=Cylinder.objects.order_by('EntryDate').last()
    
    return render(request,'entry/cylinderList.html', {'cylinder': cylinder}) 

В этом случае вы не повторяете cylinder , так как это не набор Cylinder s, а один Cylinder .

или, если вы хотите, чтобы элемент с определенным идентификатором был последним, вы можете работать с:

 from django.db.models import BooleanField, ExpressionWrapper, Q

def cylinderListView(request):
    # specific id
    specific_id = 42  # expression for a certain value
    cylinders = Cylinder.objects.prefetch_related().order_by(
        ExpressionWrapper(
            Q(pk=specific_id),
            output_field=BooleanField()
        ).asc(),
        '-EntryDate'
    )
    
    return render(request,'entry/cylinderList.html', {'cylinders': cylinders}) 

В этом случае лучше назвать переменную cylinders , так как она представляет собой набор из нуля, одного или нескольких Cylinder s.

Комментарии:

1. Я хочу отобразить все записи в цилиндре, но я хочу, чтобы соответствующая запись о проблеме для этого конкретного идентификатора цилиндра была последней.

2. @ShagunRaghav: тогда вы сначала делаете заказ на основе условия, см. Редактирование.

3. Я попытался выполнить ваше предложение, но это не меняет производительности

4. @ShagunRaghav: но это не изменит производительность, он установит Cylinder specified_id первичный ключ в качестве первого элемента в наборе запросов, вот и все. Если бы можно было повысить производительность, то не было бы причин для использования и т. Д. .all()

5. я хочу сказать, что это не приводит к тому, чего я хочу, извините, если я не был ясен с моим вопросом, поэтому запрос, который я хочу выполнить, заключается в том, что ….если в цилиндре есть две записи о проблеме, то запись о проблеме, которая была создана недавно или которая ближе к настоящему времени, будет отображаться вместе с записью о цилиндре. Для этого что я должен сделать