#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. я хочу сказать, что это не приводит к тому, чего я хочу, извините, если я не был ясен с моим вопросом, поэтому запрос, который я хочу выполнить, заключается в том, что ….если в цилиндре есть две записи о проблеме, то запись о проблеме, которая была создана недавно или которая ближе к настоящему времени, будет отображаться вместе с записью о цилиндре. Для этого что я должен сделать