Django: удалить запись после обновления и записать ее в другую модель
Как сделать чтобы при обновлении / редактировании записи из списка, запись удалялась из исходной модели и уже новой, обновленной записывалась в другую модель? Сейчас при обновлении / редактировании записи она просто сохраняет сама себя и отображается в общем списке уже обновленной. Но если я создаю новую запись, она сохраняется корректно в новом списке.
Нужно чтобы при обновлении модели NewAnzeigen создавалась и сохранялась запись в модели Fertig а исходная запись в NewAnzeigen удалялась. Идея в том, чтобы при оброботке исходного списка в NewAnzeigen те записи, которые нужно менять сразу сохранялись в новый список, так сказать на чистовик, а в исходном списки оставались только те записи, которые еще нужно обработать.
views.py
from django.shortcuts import render, redirect
from .models import NewAnzeigen
from .models import Fertig
from .forms import NewAnzeigenForm
from django.views.generic import DetailView, UpdateView, DeleteView
class AnzeigeDetails(DetailView):
model = NewAnzeigen
template_name = 'main/details.html'
context_object_name = 'article'
class AnzeigeUpdateDetails(UpdateView):
model = NewAnzeigen
template_name = 'main/create.html'
form_class = NewAnzeigenForm
class AnzeigeDeleteDetails(DeleteView):
model = NewAnzeigen
success_url = '/'
template_name = 'main/delete.html'
class FertigDetails(DetailView):
model = Fertig
template_name = 'main/details.html'
context_object_name = 'article'
class FertigUpdateDetails(UpdateView):
model = Fertig
template_name = 'main/create.html'
form_class = NewAnzeigenForm
class FertigDeleteDetails(DeleteView):
model = Fertig
success_url = '/fertig'
template_name = 'main/delete.html'
def index(request):
anzeigen = NewAnzeigen.objects.all()
return render(request, 'main/index.html', {'anzeigen': anzeigen})
def fertig(request):
fertigeanzeige = Fertig.objects.all()
return render(request, 'main/ready.html', {'fertigeanzeige': fertigeanzeige})
def create(request):
error = ''
if request.method == 'POST':
form = NewAnzeigenForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
error = 'Ooopps.. Fehler...'
form = NewAnzeigenForm()
data = {
'form': form,
'error': error
}
return render(request, 'main/create.html', data)
forms.py
from .models import NewAnzeigen
from .models import Fertig
from django.forms import ModelForm, TextInput, Textarea, ChoiceField
from django import forms
class NewAnzeigenForm(ModelForm):
class Meta:
model = Fertig
RASSEN = (
('araber', 'Araber'),
('ha', 'Hispano-Araber'),
('cruzado', 'Cruzado'),
('lustiano', 'Lustiano'),
('pre', 'PRE'),
('muli', 'Muli'),
('esel', 'Esel'),
)
FARBE = (
('falbe', 'Falbe'),
('bucksin', 'Bucksin'),
('schimmel', 'Schimmel'),
('rappe', 'Rappe'),
('schecke', 'Schecke'),
('ps', 'Porzellanschecke'),
('fuchs', 'Fuchs'),
('brauner', 'Brauner'),
('champagne', 'Champangne'),
('cremello', 'Cremello'),
('palomino', 'Palomino'),
('tg', 'Tigerschecke'),
)
ART = (
('fohlen', 'Fohlen'),
('stute', 'Stute'),
('hengst', 'Hengst'),
('wallach', 'Wallach'),
)
AUSBILDUNG = (
('ungeritten', 'Ungeritten'),
('geritten', 'Geritten'),
('hs', 'Hohe Schule'),
('zucht', 'Zucht'),
)
ABSTAMMUNG = (
('ja', 'Ja'),
('nein', 'Nein'),
)
widget = forms.Select(attrs={'class':'form-control'})
rasse = ChoiceField(choices=RASSEN, widget=forms.Select(attrs={'class':'form-control'}))
art = ChoiceField(choices=ART, widget=forms.Select(attrs={'class': 'form-control'}))
abstammung = ChoiceField(choices=ABSTAMMUNG, widget=forms.Select(attrs={'class': 'form-control'}))
ausbildung = ChoiceField(choices=AUSBILDUNG, widget=forms.Select(attrs={'class': 'form-control'}))
farbe = ChoiceField(choices=FARBE, widget=forms.Select(attrs={'class': 'form-control'}))
fields = ['name', 'beschreibung', 'preis', 'standort', 'telefon', 'alter', 'geschlecht', 'grosse', 'rasse', 'art', 'abstammung', 'farbe', 'ausbildung']
widgets = {
'name': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Name eingeben'
}),
'beschreibung': Textarea(attrs={
'class': 'form-control',
'placeholder': 'Beschreibung eingeben'
}),
'preis': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Preis eingeben'
}),
'standort': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Ort / Land eingeben'
}),
'telefon': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Telefonnummer eingeben'
}),
'alter': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Alter eingeben'
}),
'grosse': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Größe in cm. eingeben'
}),
'geschlecht': TextInput(attrs={
'class': 'form-control',
'placeholder': 'Geschlecht eingeben'
}),
}
models.py
from django.db import models
import csv
class NewAnzeigen(models.Model):
RASSEN = (
('Araber', 'Araber'),
('Hispano-Araber', 'Hispano-Araber'),
('Cruzado', 'Cruzado'),
('Lustiano', 'Lustiano'),
('PRE', 'PRE'),
('Muli', 'Muli'),
('Esel', 'Esel'),
)
ART = (
('Fohlen', 'Fohlen'),
('Stute', 'Stute'),
('Hengst', 'Hengst'),
('Wallach', 'Wallach'),
)
AUSBILDUNG = (
('Ungeritten', 'Ungeritten'),
('Geritten', 'Geritten'),
('Hohe Schule', 'Hohe Schule'),
('Zucht', 'Zucht'),
)
ABSTAMMUNG = (
('Ja', 'Ja'),
('Nein', 'Nein'),
)
FARBE = (
('Falbe', 'Falbe'),
('Bucksin', 'Bucksin'),
('Schimmel', 'Schimmel'),
('Rappe', 'Rappe'),
('Schecke', 'Schecke'),
('Porzellanschecke', 'Porzellanschecke'),
('Fuchs', 'Fuchs'),
('Brauner', 'Brauner'),
('Champangne', 'Champangne'),
('Cremello', 'Cremello'),
('Palomino', 'Palomino'),
('Tigerschecke', 'Tigerschecke'),
)
name = models.CharField('Name', max_length=255)
preis = models.CharField('Preis', max_length=255)
telefon = models.CharField('Telefon', max_length=255)
beschreibung = models.TextField('Beschreibung')
anzeigenummer = models.CharField('Anzeigenummer', max_length=255)
standort = models.CharField('Standort', max_length=500)
online = models.CharField('Online seit', max_length=255)
url = models.CharField('URL', max_length=1000)
bild = models.CharField('Bild', max_length=1000)
rasse = models.CharField('Rasse', max_length=255, choices=RASSEN, default='')
alter = models.CharField('Alter', max_length=255, default=1)
grosse = models.CharField('Grosse', max_length=255, default=100)
geschlecht = models.CharField('Geschlecht', max_length=255, default='')
art = models.CharField('Art', max_length=255, choices=ART, default='')
ausbildung = models.CharField('Ausbildung', max_length=255, choices=AUSBILDUNG, default='')
abstammung = models.CharField('Abstammung', max_length=255, choices=ABSTAMMUNG, default='')
farbe = models.CharField('Farbe', max_length=255, choices=FARBE, default='')
def __str__(self):
return self.name
def get_absolute_url(self):
return f'/{self.id}'
class Meta:
verbose_name = 'Anzeige'
verbose_name_plural = 'Anzeigen'
with open('main/daten.csv', encoding='utf-8') as File:
reader = csv.reader(File, delimiter=';')
for row in reader:
_, created = NewAnzeigen.objects.get_or_create(
name = row[0],
preis = row[1],
telefon = row[2],
beschreibung = row[3],
anzeigenummer = row[4],
standort = row[5],
online = row[6],
url = row[7],
bild = row[8]
)
class Fertig(models.Model):
RASSEN = (
('Araber', 'Araber'),
('Hispano-Araber', 'Hispano-Araber'),
('Cruzado', 'Cruzado'),
('Lustiano', 'Lustiano'),
('PRE', 'PRE'),
('Muli', 'Muli'),
('Esel', 'Esel'),
)
ART = (
('Fohlen', 'Fohlen'),
('Stute', 'Stute'),
('Hengst', 'Hengst'),
('Wallach', 'Wallach'),
)
AUSBILDUNG = (
('Ungeritten', 'Ungeritten'),
('Geritten', 'Geritten'),
('Hohe Schule', 'Hohe Schule'),
('Zucht', 'Zucht'),
)
ABSTAMMUNG = (
('Ja', 'Ja'),
('Nein', 'Nein'),
)
FARBE = (
('Falbe', 'Falbe'),
('Bucksin', 'Bucksin'),
('Schimmel', 'Schimmel'),
('Rappe', 'Rappe'),
('Schecke', 'Schecke'),
('Porzellanschecke', 'Porzellanschecke'),
('Fuchs', 'Fuchs'),
('Brauner', 'Brauner'),
('Champangne', 'Champangne'),
('Cremello', 'Cremello'),
('Palomino', 'Palomino'),
('Tigerschecke', 'Tigerschecke'),
)
name = models.CharField('Name', max_length=255)
preis = models.CharField('Preis', max_length=255)
telefon = models.CharField('Telefon', max_length=255)
beschreibung = models.TextField('Beschreibung')
anzeigenummer = models.CharField('Anzeigenummer', max_length=255)
standort = models.CharField('Standort', max_length=500)
online = models.CharField('Online seit', max_length=255)
url = models.CharField('URL', max_length=1000)
bild = models.CharField('Bild', max_length=1000)
rasse = models.CharField('Rasse', max_length=255, choices=RASSEN, default='')
alter = models.CharField('Alter', max_length=255, default=1)
grosse = models.CharField('Grosse', max_length=255, default=100)
geschlecht = models.CharField('Geschlecht', max_length=255, default='')
art = models.CharField('Art', max_length=255, choices=ART, default='')
ausbildung = models.CharField('Ausbildung', max_length=255, choices=AUSBILDUNG, default='')
abstammung = models.CharField('Abstammung', max_length=255, choices=ABSTAMMUNG, default='')
farbe = models.CharField('Farbe', max_length=255, choices=FARBE, default='')
def __str__(self):
return self.name
def get_absolute_url(self):
return f'/{self.id}'
class Meta:
verbose_name = 'Fertig'
verbose_name_plural = 'Fertig'
Ответы (1 шт):
Самый быстрый способ - в форме переопределить save
def save(self, *args, **kwargs):
source_instance = super().save(*args, **kwargs)
new_instance = Fertig()
for field in [ # поля можно в принципе подтянуть из Fertig._meta.fields или из других св-в Fertig._meta
'name', 'preis', ..., 'farbe'
]:
setattr(new_instance, field, getattr(source_instance, field, None))
new_instance.save()
source_instance.delete() # или remove, не помню
return new_instance
Но это не совсем правильный вариант, так как вернется объект не того типа, который указан в Meta формы.
Чтобы было более корректно, наверное лучше сделать от Form класса, или еще как. Либо указать в комменте где то , что вернется объект другого типа, чтобы потом у вас не было проблем с отладкой
А как это корректно реализовать с BooleanField чтобы на одной странице отображались все записи с False а на другой с True ?
Пример модели
class ExampleAnzeigen(models.Model)
class Meta:
...
field1 = ...
is_draft = models.BooleanField(default=True, db_index=True) # Для вашего варианта True вроде подходит, db_index для ускорения
...
На одной странице отображаете ExampleAnzeigen.objects.filter(is_draft=True) на другой ExampleAnzeigen.objects.filter(is_dradft=False)
Можно вынести в менеджер объектов
class ExampleAnzeigenManager(models.Manager):
def draft_only(self)
return seflf.filter(is_draft=True)
def not_draft_only(self)
return seflf.filter(is_draft=False)
class ExampleAnzeigen(models.Model):
....
objects = ExampleAnzeigenManager()
Тогда там где черновики, выводите ExampleAnzeigen.objects.draft_only() а на чистовиках ExampleAnzeigen.objects.not_draft_only()
Изменить черновик на чистовик - в save() формы от ModelForm
def save(self, *args, **kwargs):
instance = super().save(commit=False)
instance.is_draft = False
instance.save()
self._save_m2m()
return instance