Данные внешних ключей не сохраняются во вложенных инлайнах в админке django
Я пытаюсь построить список реплицируемых полей, порядок которых можно менять.
Для этого я построил три различные модели Multicap Multitext Multimg
, которые являются инлайнами модели Multis
, которая является инлайном модели Delta
.
Я использую django-nested-admin и все работает нормально на странице администратора, я могу добавлять новые объекты и изменять их порядок.
Проблема заключается в том, что когда я заполняю поля, сохраняю модель и затем проверяю ее содержимое, все данные текстовых полей превращаются в нули 0.
Вместо этого, когда я пытаюсь сохранить изображение, я получаю эту ошибку:
AttributeError: 'int' object has no attribute 'field'
models.py
class Multis(models.Model):
name = models.TextField(max_length=50, null=True, blank=True)
delta = models.ForeignKey('Delta', related_name="delta", null=True, on_delete=models.CASCADE)
class Meta:
ordering = ('name',)
def __str__(self):
return str(self.name)
class Multicap(models.Model):
caption = models.TextField(max_length=50, null=True, blank=True)
multic = models.ForeignKey('Multis', related_name="multicap", null=True, on_delete=models.CASCADE)
class Meta:
ordering = ('caption',)
def __str__(self):
return str(self.caption)
class Multimg(models.Model):
img = models.ImageField(upload_to="images", verbose_name='Image', null=True, blank=True,)
multim = models.ForeignKey('Multis', related_name="multimg", null=True, on_delete=models.CASCADE)
class Meta:
ordering = ('img',)
@property
def img_url(self):
if self.img and hasattr(self.img, 'url'):
return self.img.url
def get_image_filename(instance, filename):
title = instance.post.title
slug = slugify(title)
return "post_images/%s-%s" % (slug, filename)
def get_absolute_url(self):
return reverse('delta-detail', kwargs={'pk': self.pk})
class Multitext(models.Model):
text = tinymce_models.HTMLField(null=True, blank=True)
multit = models.ForeignKey('Multis', related_name="multitext", null=True, on_delete=models.CASCADE)
class Meta:
ordering = ('text',)
def __str__(self):
return str(self.text)
class Delta(models.Model):
heading = models.CharField(max_length=50, null="true")
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
ordering = ('heading',)
def __str__(self):
return str(self.heading)
def get_absolute_url(self):
return reverse('delta-detail', kwargs={'pk': self.pk})
admin.py
from django.contrib import admin
import nested_admin
from nested_admin import SortableHiddenMixin, NestedTabularInline, NestedModelAdmin, NestedStackedInline
from .models import Delta, Multimg, Multitext, Multicap, Multis
class MimgAdmin(nested_admin.NestedStackedInline):
model = Multimg
sortable_field_name = "img"
extra = 0
class MtxtAdmin(nested_admin.NestedStackedInline):
model = Multitext
sortable_field_name = "text"
extra = 0
class McapAdmin(nested_admin.NestedStackedInline):
model = Multicap
sortable_field_name = "caption"
extra = 0
class MAdmin(nested_admin.SortableHiddenMixin, nested_admin.NestedStackedInline):
model = Multis
sortable_field_name = "name"
extra = 0
inlines = [ McapAdmin, MtxtAdmin, MimgAdmin ]
@admin.register(Delta)
class DeltaAdmin(nested_admin.NestedModelAdmin):
sortable_field_name = "delta"
inlines = [ MAdmin ]
Решено. Это была глупая ошибка, связанная с sortable_field_name
Это поле должно быть связано с полем в модели, которое должно быть сформулировано таким образом:
models.py
position = models.PositiveSmallIntegerField("Position", null=True)
admin.py
sortable_field_name = 'position'
Это формирует позиционное поле, которое имеет базовое значение 0. Делая так, как я делал, это значение подставлялось в поле, которое я хотел заполнить.
Надеюсь, это может помочь кому-то, кто сталкивается с той же ошибкой