Django - Feldinhalte von Models manipulieren

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
oshoki
User
Beiträge: 30
Registriert: Donnerstag 3. Januar 2008, 22:49

Montag 27. April 2009, 15:42

Folgende Situation sei exemplarisch gegeben.
Ein Model mit drei Feldern:
meeting (CharField)
meeting_date (DateField)
Entry (TextField)

Für zwei Felder werden die Eingaben gesteuert mittels
class MyEntryAdminForm(forms.ModelForm):

entsprechend mit clean_meeting(self) und clean_entry(self)

Folgendes Problem möchte ich gerne gelöst haben:
Das Meeting-Feld setzt sich aus zwei Teilen zusammen: Datum und Textzusatz.
Es soll das Datum aus dem Feldinhalt von meeting extrahiert werden (das klappt ja auch wunderbar) und dem Feld meeting_date zugeordnet werden (das klappt nun nicht mehr).

Das ist der Punkt. Wie und wo kann ich das Extrakt dem Feld zuweisen und im Model abspeichern.
In Form mit clean(self) => cleaned_data['meeting_date'] = extrakt_aus_meeting bekomme ich das nicht hin.

Mir fehlen die Kenntnisse, wie ich ein Datensatz-Feld (Model-Feld) befüllen kann, das kein Eingabefeld in der Form hat.
Vielen Dank für Unterstützung im Voraus
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Montag 27. April 2009, 17:25

Naja, MyModel.myfield = myvalue.

Du könntest das (sofern dein Webframework sowas anbietet) mit Signalen/Events arbeiten.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Montag 27. April 2009, 20:11

Noch ein Fall für `save_model`, würde ich sagen:

Code: Alles auswählen

class FooAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj.meeting_date = extract_somehow(obj.meeting)
        obj.save()
Stefan
oshoki
User
Beiträge: 30
Registriert: Donnerstag 3. Januar 2008, 22:49

Dienstag 28. April 2009, 12:18

Sorry, ich habe es noch nicht verstanden
Ich habe Folgendes:


Code: Alles auswählen

class Meeting(models.Model):
    date = models.DateTimeField(default=datetime.datetime.now)
    team = models.CharField(max_length=100)

    class Meta:
        verbose_name_plural = u'Meetings'
        ordering = ['-date', 'team']

    def __unicode__(self):
        return u'%s %s' % (self.date, self.team)



class Entry(models.Model):
    INFO_STATUS = 1
    TODO_STATUS = 2
    STATUS_CHOICES = (
        (INFO_STATUS, 'Info'),
        (TODO_STATUS, 'ToDo'),
    )
    meeting = models.ForeignKey(Meeting, blank=True)
    meeting_date = models.DateField(null=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(null = True)
    title = models.CharField(max_length=100)
    description = models.TextField()
    choice = models.IntegerField(choices=STATUS_CHOICES, default=INFO_STATUS)
    responsible = models.CharField(max_length=50, blank=True)
    due_date = models.DateField(null=True)

    class Meta:
        verbose_name_plural = u'Entries'

    def __unicode__(self):
        return self.title
Sodann habe ich die Form:

Code: Alles auswählen

from django import forms
import datetime
import time
from meetings.meeting.models import Meeting
from meetings.meeting.models import Entry
from django.contrib.admin import widgets

class MyEntryAdminForm(forms.ModelForm):
    class Meta:
        model = Entry
    
    due_date = forms.DateField(widget=widgets.AdminDateWidget(), required=False)
    meeting = forms.ModelChoiceField(queryset=Meeting.objects.all(), empty_label=None)

    # Schlagzeile sollte aus mehr als einem Wort bestehen
    def clean_title(self):
        title = self.cleaned_data['title']
        num_words = len(title.split())
        if num_words < 2:
            raise forms.ValidationError('Ein Wort reicht nicht im Titel')
        return title

    # Description sollte aus mehr als zwei Worte bestehen
    def clean_description(self):
        description = self.cleaned_data['description']
        num_words = len(description.split())
        if num_words < 3:
            raise forms.ValidationError('Ein ganzer Satz sollte es schon sein')
        return description


    def clean(self):
        cleaned_data = self.cleaned_data
        meeting_date = str(cleaned_data['meeting'])[0:10]
In def clean(self) extrahiere ich das Datum aus dem Ausdruck meeting und möchte nun den Variableninhalt von meeting_date in das Datensatzfeld meeting_date speichern. Meeting_date hat kein Input-Feld in der Form. Dieser Sachverhalt ist stellvertretend für das generelle Problem, das sich mir stellt. Ich habe nicht verstanden, wie ich zum Beispiel Variablen-Inhalte von forms.py nach admin.py transportiere.

Code: Alles auswählen

from django.contrib import admin
from meetings.meeting.forms import MyEntryAdminForm
from meetings.meeting.models import Entry, Meeting

class MeetingAdmin(admin.ModelAdmin):
    fields = ('date', 'team',)
    list_display = ('date', 'team',)

class EntryAdmin(admin.ModelAdmin):
    #exclude = ('meeting_date',)
    fields = ('meeting', 'title', 'description',
              'choice', 'responsible', 'due_date',)
    list_display = ('meeting', 'meeting_date', 'title', 'choice', 'created',
                     'modified', 'due_date')

    #def save_model(self, request, obj, form, change):
    #    obj.meeting_date = meeting_date
    #    obj.save()


    form = MyEntryAdminForm


admin.site.register(Entry, EntryAdmin)
admin.site.register(Meeting, MeetingAdmin)
Wie kann ich dann den Variableninhalt von meeting_date in admin.py und def_save_model speichern?

Das Beispiel von meeting_date soll stellvertretend das generelle Problem widerspiegeln, das sich mir stellt
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Dienstag 28. April 2009, 15:28

oshoki hat geschrieben:möchte nun den Variableninhalt von meeting_date in das Datensatzfeld meeting_date speichern. Meeting_date hat kein Input-Feld in der Form.
Wo soll denn dann der Variableninhalt herkommen?
oshoki
User
Beiträge: 30
Registriert: Donnerstag 3. Januar 2008, 22:49

Dienstag 28. April 2009, 16:45

Aus dem Extrakt eines Datenfeldes das in der Form verfügbar ist.

Das hier funktioniert:

Code: Alles auswählen

    def save_model(self, request, obj, form, change):
        obj.meeting_date = str(obj.meeting)[0:16]
        obj.save()
Der Feldinhalt von meeting wird partiell ausgelesen und einem anderen Feld zugewiesen. Aber es beantwortet meine Frage noch nicht.
Wie sieht es denn damit aus:
Ich hole den Feldinhalt von meeting in der Form:

Code: Alles auswählen

meeting_date = str(cleaned_data['meeting'])[0:10]
und weise ihn der Variablen meeting_date zu. Wie kann ich denn nun die Variable meeting_date in admin.py mit def save_model ansprechen?
Antworten