Seite 1 von 1
Initiale Werte einer Inline-Instanz in Django-Admin
Verfasst: Montag 28. Oktober 2019, 07:57
von Bolitho
Hallo,
ich habe die folgenden Modelle:
Code: Alles auswählen
#models.py
class Termin(models.Model):
start = models.DateTimeField()
klasse = models.ForeignKey(
'Klasse', on_delete=models.CASCADE, related_name="termin")
....
class Klasse(models.Model):
....
und wie folgt im Admin registriert:
Code: Alles auswählen
# admin.py
...
class TerminInline(admin.TabularInline):
model = Termin
extra = 0
class KlasseAdmin(admin.ModelAdmin):
inlines = [
TerminInline,
]
admin.site.register(Klasse, KlasseAdmin)
...
Ich würde gerne erreichen, dass für neue TerminInlines wie folgt initiale Daten gesetzt werden.
- Für den ersten Termin keine initialen Daten
- Ab dem zweiten Termin soll die Startzeit genau eine Woche späte sein (wie ich das mit der Zeitspanne hinbekomme ist mir klar, also über timedelta)

(wg. Alltagskurs Erziehung, es handelt sich um ein Projekt für eine Hundeschule, dass ich ohne Bezahlung umsetze)
Beim Eintragen der Inlines sind die Daten ja noch nicht gespeichert. Kann ich dieses Verhalten dann überhaupt realisieren? Oder muss ich zumindest den ersten Termin zusammen mit der neuen Klasse speichern?
Ich finde hier keinen Ansatzpunkt, wie ich das umsetzen kann. Vermutlich brauche ich die get_formset()-Methode aus dem TabularInline. Aber da ist mir nicht ganz klar, wie ich an die Daten komme und die initialen Werte setze.
Feedback wäre klasse.
Re: Initiale Werte einer Inline-Instanz in Django-Admin
Verfasst: Montag 28. Oktober 2019, 11:17
von sparrow
Kannst du vollständig benutzbare model.py und admin.py posten. Dann schau ich mir das mal an.
Re: Initiale Werte einer Inline-Instanz in Django-Admin
Verfasst: Montag 28. Oktober 2019, 12:16
von Bolitho
Code: Alles auswählen
#models.py
from django.db import models
class Termin(models.Model):
start = models.DateTimeField()
klasse = models.ForeignKey(
'Klasse', on_delete=models.CASCADE, related_name="termin")
class Klasse(models.Model):
klassenname = models.CharField(max_length=120)
Code: Alles auswählen
# admin.py
from django.contrib import admin
from .models import Termin, Klasse
class TerminAdmin(admin.ModelAdmin):
pass
admin.site.register(Termin, TerminAdmin)
class TerminInline(admin.TabularInline):
model = Termin
extra = 0
class KlasseAdmin(admin.ModelAdmin):
inlines = [
TerminInline,
]
admin.site.register(Klasse, KlasseAdmin)
Danke für deine Mühe.
Meine Modelle sind natürlich umfangreicher, aber das spielt nicht in die Fragestellung hinein. Bei Bedarf gebe ich dir gerne Zugang zum vollständigen Code und zum Testserver Admin-Bereich.
Re: Initiale Werte einer Inline-Instanz in Django-Admin
Verfasst: Montag 28. Oktober 2019, 12:54
von sparrow
Nur zum Verständnis: Du möchtest, dass - wenn du einen neuen Termin einträgst - automatisch das DateTimeField für start gefüllt wird, und zwar abhängig zum vorherigen Termin?
Re: Initiale Werte einer Inline-Instanz in Django-Admin
Verfasst: Montag 28. Oktober 2019, 14:42
von Bolitho
Ja, genau. genau genommen zum vorherigen Termin zur gleichen Klasse-Instanz. Beim Eintragen (vor dem Speichern) ist das wahrscheinlich nicht möglich. Dann aber zumindest so, dass ich die Klasse mit einem Termin anlege , dann speichere und wenn ich jetzt wieder die Klasse aufrufe und einen neuen Termin eintrage der Starttermin abhängig vom Starttermin des vorherigen Termin vorgeschlagen wird.
Eigentlich geht es insbesondere um die Uhrzeit. Nervt halt, wenn man für jede Klasse bei jedem Termin immer wieder die gleiche Uhrzeit einträgt (jede Klasse hat in der Regel sechs Termine). Leider ist es aber eben nicht in 100% der Fälle die gleiche Uhrzeit. Sonst könnte man ja ein TimeField in der Klasse setzen und dann das start-DateTimeField bei Bedarf bilden.
Ich könnte natürlich auch für die Pflege der Klassen einen Pflegeview für admins programmieren und das ganze über Javascript lösen. Aber da alles andere Adminbereich von Django gepflegt wird, wäre mir eine Lösung dort lieber.
Re: Initiale Werte einer Inline-Instanz in Django-Admin
Verfasst: Montag 28. Oktober 2019, 14:48
von sparrow
Und was machst du, wenn der Benutzer nicht nur 1 sondern 2 oder 6 Termine hinzufügt? Die sind dann ja nur im Frontend bekannt, bis sie gespeichert sind.
Ich würde das tatsächlich in JavaScript lösen, allerdings im
Admin-Bereich.
Immer wenn ein neuer Termin hinzugefügt wird, schauen ob es schon einen auf der Seite gibt, ob der Datum und Zeit trägt und das dann in dem neuen Datensatz eintragen. Ich denke, das wäre die beste Möglichkeit.
Wenn ich heute Abend früh daheim sein sollte, schaue ich mal, wie schwer das ist. Aber JavaScript ist nicht so meins.
Re: Initiale Werte einer Inline-Instanz in Django-Admin
Verfasst: Montag 28. Oktober 2019, 15:06
von Bolitho
Danke für den Link zur Admin-Customization. Man lernt nie aus, kannte ich noch überhaupt nicht. Aber das könnte klappen. Setze mich morgen mal ran und berichte.
Re: Initiale Werte einer Inline-Instanz in Django-Admin
Verfasst: Dienstag 29. Oktober 2019, 13:08
von Bolitho
@sparrow: vielen Dank für den Hinweis. Ist relativ simpel, wenn man weiß wie es geht.
Lösung:
Code: Alles auswählen
# change_form.html in tempates/admin/training (app_name)
{% extends 'admin/change_form.html' %}
{% load static %}
{% block admin_change_form_document_ready %}
{{ block.super }}
<script type="text/javascript" src="{% static 'app/formset_handlers.js' %}"></script>
{% endblock %}
Code: Alles auswählen
#formset_handlers.js in static/app
(function ($) {
$(document).on('formset:added', function (event, $row, formsetName) {
if (formsetName == 'termin') {
let id = $row[0].id.substr($row[0].id.length - 1);
if (id > 0) {
let source_id = '#id_termin-' + (id - 1) + '-start_1'
let destination_id = '#id_termin-' + id + '-start_1'
let source = $(source_id)[0].value
let destination = $(destination_id)
destination.val(source)
}
}
});
})(django.jQuery);
bin auch kein JS und JQuery crack, da gibt es bestimmt noch Optimierungen
