2016-05-10 11 views
1

Ich habe zwei ModellePython Django zurückkehren einzigartige speichern Daten und Filtermodell Objekte

Zimmer und RoomLog

jedes einzelne Zimmer-Objekt kann mehrere RoomLog Objekte. Der Zweck davon ist, dass Raumobjekt ein Attribut hat: Wert und Methode save(). Ich erstelle jedes Mal ein neues verwandtes RoomLog-Objekt, wenn ein Benutzer das geänderte Attribut eines bestimmten Room-Objekts speichert und speichert.

Das RoomLog-Objekt hat ein Wertattribut und ein Datumsattribut. Das Datum bezieht sich auf die Methode zum Speichern von Räumen, so dass der Wert für den Raum geändert wird, um DATUM zu speichern.

Meine Frage ist:

Q1: Wie alle einzigartigen Tage von allen RoomLog zurückzukehren Objekte, damit ich weiß, wenn eine speichern stattfand?

Q2: Sagen wir, wir wissen, wie man einzigartige Tage zurückgibt. Die Frage ist also: Wie kann man einen Tag aus diesen eindeutigen Tagen auswählen und alle Werte der Raumobjekte nach dem gewählten Datum anzeigen? Ich möchte den zuletzt gespeicherten Wert vom ausgewählten Datum für jedes Room-Objekt zurückgeben.

So wie ich im Moment beide Fragen angehen (ich suche mehr Pythonic, schneller, leistungsfähigere Lösungen) ist:

I-Formular erstellt, in dem ich durchlaufen RoomLog Objekte:

class MyForm(forms.Form): 
    roomdates = [] 
    roomextracted = [] 
    for r in RoomLog.objects.all(): 
     if r not in roomdates: 
      roomdates.append(r.update_date) 
    for i in roomdates: 
     if i not in roomextracted: 
      roomextracted.append(i) 

    ROOMDATA = [(r, r) for r in roomextracted] 
    my_choice_field = forms.ChoiceField(choices=ROOMDATA) 

dann habe ich eine Ansicht ausgewähltes Datum in einer anderen Ansicht passieren, in der I Room.objects.all() durch die gewählte Datum filtern:

def choices(request): 

    form = RoomLogChoices() 
    form.fields['choice'].choices = list() 
    testlist = [] 
    for rl in RoomLog.objects.all(): 
     if rl.update_date not in testlist: 
      testlist.append(rl.update_date) 
    for d in testlist: 
     form.fields['choice'].choices.append(
       (
        d,d 
       ) 
     ) 


    return render(request, 'prostats/choices.html', {'form':form}) 

nächste I choicesform.html habe in die ich wähle Datum aus Dropdown-Menü:

{% extends "base.html" %} 
{% block content %} 

<form action="" method="post" > 
{% csrf_token %} 

<ul> 
{% for choice in form.my_choice_field.field.choices %} 
    <li> 
    <input type="radio" name="my_choice_field" value="{{choice.0}}" 
     {% if equal form.my_choice_field.data choice.0 %} 
     checked="checked" 
     {% endifequal %}/> 
    <label for="">{{choice.1}}</label> 
    </li> 
{% endfor %} 
</ul> 

<input type="submit" value="Submit" /> 
</form> 

{% endblock %} 

und dies ist die Ansicht, in der ich POST-Daten verarbeiten

class AllRoomsView(ListView): 
    template_name = 'prostats/roomsdetail.html' 
    queryset = Room.objects.all() 

    def get_context_data(self, **kwargs): 


     context = super(AllRoomsView, self).get_context_data(**kwargs) 

     context['rooms'] = Room.objects.all() 
     context['rlog'] = RoomLog.objects.all() 



     roomsdates = [] 

     for r in context['rlog']: 
      if r not in roomsdates: 
       roomsdates.append(r.update_date) 

     roomextracted = [] 
     for i in roomsdates: 
      if i not in roomextracted: 
       roomextracted.append(i) 

     context['roomextracted'] = roomextracted 
     choicedate = self.request.GET.get('choice') 
     if choicedate != None: 
      choosend = choicedate 
     else: 
      choosend = '2016-02-01' 



     #filtered rlogs 
     rlfilteredempty = [] 
     for r in context['rooms']: 
      i = RoomLog.objects.filter(room=r.id, update_date__lte = choosend).order_by('-update_date')[:1] 
      if i: 
       rlfilteredempty.append(i[0]) 
      else: 
       rlfilteredempty.append(r) 
     context['rlfiltered'] = rlfilteredempty 




     context['choicedate'] = self.request.GET.get('choice') 
     #context['roomfiltersettime'] = RoomLog.objects.filter(update_date__lte = choosend) 
     context['roomfiltersettime'] = RoomLog.objects.filter(update_date__lte = choosend) 

     rslice = [] 
     for r in context['rooms']: 
      i = RoomLog.objects.filter(room=r.id, update_date__lte = choosend).order_by('-update_date')[:1] 
      if i: 
       for rsobject in i: 
        rs = (r.flat.flat_number,r.flat.block.block_name,r.room_name) 
        rl = rsobject.id 
        rv = rsobject.room_value 
        rslice.append((rs,rl,rv)) 
      else: 
       rs = (r.flat.flat_number,r.flat.block.block_name,r.room_name) 
       r = r.id 
       rslice.append((rs,r)) 

     context['rslice'] = rslice 

Also, alles das, was ich habe ich getan, das Gefühl ist nicht sehr gut und vielleicht kann mir jemand gute Ideen geben, wie man dieses Problem besser angehen kann?


EDIT: Aktualisierung der Post mit meinem Zimmer und RoomLog Modelle:

class Room(models.Model): 
    room_name = models.CharField(max_length= 10) 
    room_value = models.PositiveSmallIntegerField(default=0) 
    flat = models.ForeignKey(Flat) 
    created_date = models.DateField(auto_now_add= True) 
    created_time = models.TimeField(auto_now_add= True) 
    substage_name = models.CharField(max_length=50,default="") 

    def __init__(self, *args, **kwargs): 
     super(Room, self).__init__(*args, **kwargs) 
     self.value_original = self.room_value 

    def save(self, **kwargs): 
     with transaction.atomic(): 
      response = super(Room, self).save(**kwargs) 
      if self.value_original != self.room_value: 
       room_log = RoomLog() 
       room_log.room = self 
       room_log.room_value = self.value_original 
       room_log.save() 
      return response 



class RoomLog(models.Model): 
    room = models.ForeignKey(Room) 
    room_value = models.PositiveSmallIntegerField(default=0) 
    update_date = models.DateField(auto_now_add= True) 
    update_time = models.TimeField(auto_now_add= True) 

Antwort

1

Um alle einzigartigen Tagen zurückzukehren, verwenden Sie distinct() auf Ihrem created_date Feld. Das funktioniert natürlich nur, wenn created_date eigentlich ein Datum ist und kein Datetime-Wert!

RoomLog.objects.all().distinct('created_date') 

Wenn Ihr created Wert ein datetime ist, müssen Sie es zuerst ein Datum machen, mit Djangos func() und F() Funktionen. Das verwendet die DATE() SQL-Funktionen, die möglicherweise nicht in allen Datenbanken funktionieren, aber auf Postgres und wahrscheinlich vielen anderen.

Nur eine Teilantwort.Die zweite Frage hängt vom Layout Ihrer Modelle ab, die Sie nicht gepostet haben.

+0

Hallo, alles funktioniert gut (ich meine nur .distinct() ohne .annotate(). Order_by(). Distinct. Danke PS. Ich habe gerade den Beitrag bearbeitet und Modelle hinzugefügt. – BlueDog