set
является неупорядоченной структурой данных. set
, а скорее collections.OrderedDict
: >>> a = collections.OrderedDict.fromkeys([1, 2, 20, 6, 210])
>>> b = collections.OrderedDict.fromkeys([6, 20, 1])
>>> collections.OrderedDict.fromkeys(x for x in a if x not in b)
OrderedDict([(2, None), (210, None)])
Обратите внимание, что порядок b
не имеет значения, поэтому он может быть любым итерабельным, но должен быть итерабельным, который поддерживает тесты на членство O (1). Изменить: В приведенном выше ответе предполагается, что вы хотите выполнять (упорядоченно) заданные операции во всех встречающихся коллекциях, в частности, также и в результате предыдущей заданной операции. Если это не обязательно, вы можете просто использовать списки для некоторых коллекций и устанавливать для других, например
>>> a = [1, 2, 20, 6, 210]
>>> b = set([6, 20, 1])
>>> [x for x in a if x not in b]
[2, 210]
. Это теряет порядок b
, не позволяет быстро проверять членство в a
и результат. Наборы позволяют быстро проверять членство, а списки сохраняют порядок. Если вам нужны обе эти функции в одной коллекции, используйте collections.OrderedDict
.
Если Вы используете InlineForm в панели администрации, чем можно сделать как это.
, Но конечно в других случаях должен проверить также (как в DRF или ручном образцовом создании экземпляра)
from django.contrib import admin
from django.forms.models import BaseInlineFormSet, ModelForm
class AddIfAddParentModelForm(ModelForm):
def has_changed(self):
has_changed = super().has_changed()
if not self.instance.id:
has_changed = True
return has_changed
class CheckerInline(admin.StackedInline):
""" Base class for checker inlines """
extra = 0
form = AddIfAddParentModelForm
Взгляните на AutoOneToOneField в django-раздражает . Из документации:
from annoying.fields import AutoOneToOneField
class MyProfile(models.Model):
user = AutoOneToOneField(User, primary_key=True)
home_page = models.URLField(max_length=255)
icq = models.CharField(max_length=255)
(django-annoying - отличная маленькая библиотека, которая включает такие драгоценные камни, как декоратор render_to и функции get_object_or_None и get_config)
Вы можете использовать post_save-hook , который запускается после сохранения записи. Дополнительную документацию по сигналам django можно найти в здесь . На этой странице вы найдете пример того, как применить крючок к вашей модели.
Самый простой способ - переопределить метод сохранения в ModelA:
class ModelA(models.Model):
name = models.CharField(max_length=30)
def save(self, force_insert=False, force_update=False):
is_new = self.id is None
super(ModelA, self).save(force_insert, force_update)
if is_new:
ModelB.objects.create(thing=self)
Я думаю, вы хотите использовать наследование модели django . Это полезно, если верно следующее утверждение: ModelA - это ModelB (например,
класс ModelB (models.Model):
field1 = models.CharField (...)
класс ModelA (МодельB): field2 = models.CharField (...)
Теперь вы можете создать экземпляр ModelA и установить field2 и field1. Если эта модель будет сохранена, она также создаст экземпляр ModelB, которому будет присвоено значение field1. Все это делается незаметно за кулисами.
Хотя вы можете сделать следующее:
a1 = ModelA ()
a1.field1 = "foo"
a1.field2 = "бар"
a1.save ()
a2 = ModelA.objects.get (id = a1.id)
a2.field1 == "foo" # верно
a2.field2 == "bar" # верно
b1 = ModelB.objects.get (id = a1.id)
b1.field1 == "foo" # верно
# b1.field2 не определен
Просто создайте функцию, которая создает и возвращает пустой ModelA, и задайте для этой функции именованный аргумент по умолчанию для "thing".