Django OneToOneField позволяет онлайн одну ссылку - PullRequest
1 голос
/ 09 июля 2019

Я пытаюсь создать ссылку один на один и хочу убедиться, что эту ссылку нельзя использовать для другой модели или экземпляра.

Например

Скажем, у меня есть модель адреса, модель лица и модель компании

Человек имеет поле OneToOneField для адресации Компания также имеет поле OneToOneField для адреса

address=Address(data="some address")
company=Company(name="some company",address=address)
person=Person(name="my name",address=address)

Модель:

class Address(models.Model):
  data = models.CharField(max_length=255, blank=True, null=True)
class Company(models.Model):
  name = models.CharField(max_length=255, blank=True, null=True)
  address=models.OneToOneField(Address,on_delete=models.CASCADE)
class Person(models.Model):
  name = models.CharField(max_length=255, blank=True, null=True)
  address=models.OneToOneField(Address,on_delete=models.CASCADE)

Я бы хотел, чтобы система выдавала ошибку, поскольку я устанавливаю один и тот же адрес для двух разных моделей.

Также это приведет к удалению как лица, так и компании, если я удалю адрес.

Обычно вы ловите это с помощью кода и не совершаете глупую ошибку, подобную этой. Но может ли система поймать его, поскольку он один на один?

1 Ответ

0 голосов
/ 09 июля 2019

В случае удаления вы можете использовать on_delete=models.PROTECT. В другом случае вы можете добавить unique=True, чтобы у человека с идентификатором = 1 был адрес с идентификатором = 1, у человека с идентификатором = 2 больше не было адреса с идентификатором = 1. Но это решит только для одной модели:
address=models.ForeignKey(Address, unique=True, on_delete=models.PROTECT)

Новым подходом было бы создание модели для ссылки на адрес как компании, так и человека и возможность запретить создание с одним и тем же идентификатором адреса:

class AddressExample(models.Model):
    id_address = models.ForeignKey(Address, unique=True,on_delete=models.PROTECT)
    id_person = models.ForeignKey(Person, blank=True, null=True, unique=True, on_delete=models.PROTECT)
    id_company = models.ForeignKey(Person, blank=True, null=True, unique=True, on_delete=models.PROTECT)  

Обратите внимание, что я использовал blank=True, null=True, так что вы можете создать экземпляр только с человеком или компанией, без необходимости создавать экземпляр с обоими. Существует мета, чтобы использовать комбинацию первичных ключей тоже.

class AddressExample(models.Model):
    id_address = models.ForeignKey(Address, unique=True,on_delete=models.PROTECT)
    id_person = models.ForeignKey(Person, blank=True, null=True, unique=True, on_delete=models.PROTECT)
    id_company = models.ForeignKey(Person, blank=True, null=True, unique=True, on_delete=models.PROTECT)

   class Meta:
       unique_togther = ('id_address', 'id_person', 'id_company')
       # Not sure if it will throw a error here because `id_person` and `id_company` can be blank 
       # or null. But the use of `unique together` is for cases where you want to guarantee 
       # the combination of the primary keys will be unique.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...