#python #django
#python #django
Вопрос:
У меня есть FK в моей модели Django, которая должна быть уникальной для каждой существующей модели, существовавшей до миграции:
class PNotification(models.Model):
notification_id = models.AutoField(primary_key=True, unique=True)
# more fields to come
def get_notifications():
noti = PNotification.objects.create()
logger.info('Created notifiactions')
logger.info(noti.notification_id)
return noti.notification_id
class Product(models.Model):
notification_object = models.ForeignKey(PNotification, on_delete=models.CASCADE, default=get_notifications)
При миграции я получаю три PNotification
объекта, сохраненных в базе данных, однако каждый существующий Product
связан с notification_id=1, поэтому каждый существующий Product
связывается с одним и тем же PNotification
объектом. Я думал, что вызов метода default
будет выполняться для каждого существующего Product
?
Как я могу предоставить каждому существующему Product
уникальному PNotification
объекту?
Комментарии:
1. Ну
ForeignKey
, вы помещаете отношение вProduct
модель, что означает, что у каждогоProduct
может быть только одинPNotification
, но у одногоPNotification
может быть многоProduct
s — может быть, вы хотите поменять это отношение?2. Вы могли бы добавить unique=True к notification_object .
3. @ger.s.brett использование unique=True приведет к ошибкам целостности, потому что тогда каждый продукт также получит одинаковую PNotification.
4. @Daniel Это будет один, но я работаю с FK здесь для тестирования. Каждый продукт будет иметь ровно один PNotification и один PNotification принадлежит одному продукту
Ответ №1:
Я также подозревал, что новая PNotification будет создана с вашей настройкой. Похоже, что метод вызывается при объявлении класса, а не при создании экземпляра.
Может быть, переопределенный метод сохранения является лучшим подходом здесь? Обратите внимание, вам нужно будет немного изменить логику для OneToOneField
s:
class Product(models.Model):
...
def save(self, *args, **kwargs):
if not self.notification_object.all():
notification = PNotification.objects.create()
self.notification_object.add(notification)
super(Product, self).save(*args, **kwargs)
Комментарии:
1. Только один вопрос: это не поможет с миграцией, не так ли? Для вновь созданных продуктов мой код работает, речь идет только о миграции
2. Это хороший момент, но вы можете легко добавить:
for p in Product.objects.all(): p.save()
где-нибудь в вашем коде временно, чтобы запустить метод сохранения для существующих объектов во время миграции / подключения к определенному представлению и т.д. Обычно это то, что я делаю при внесении изменений в существующие экземпляры.3. Да, я думаю, что это намного проще, чем писать сценарий миграции или SQL