روابط بین مدل ها درجنگو


#1

سلام . تو روابط بین مدلها در جنگو کلی مشکل دارم . برای مثال من 5 تا مدل دارم که دارای رابطه یک به یک - چند به یک و چند به چند هستند . سناریوش اینه :

  • هر User رابطه یک به یک با Profile دارد.
  • هر User رابطه یک به یک با PhoneNumber دارد.
  • هر User رابطه چند به چند با Role دارد .
  • هر Comment رابطه چند به یک با User دارد .

با این پیاده سازی وقتی نمودار ERD رو میبینم روابط چند به یک و چند به چند درسته اما رابطه یک به یک به صورت چند به یک در اومده . کسی میدونه مشکل چیه ؟ پیاده سازی ای که کردم اینه :

    from django.db import models


    class PhoneNumber(models.Model):
        Number = models.IntegerField()


    class Profile(models.Model):
        ImagePath = models.CharField(max_length=100)


    class Role(models.Model):
        ROLE_CHOICES = (
            ("STUDENT", 'student'),
            ("TEACHER", 'teacher'),
        )
        id = models.PositiveSmallIntegerField(
            choices=ROLE_CHOICES, primary_key=True)


    class MyUser(models.Model):
        Name = models.CharField(max_length=10)
        PhoneNumber = models.OneToOneField(PhoneNumber, on_delete=models.CASCADE)
        Profile = models.OneToOneField(Profile, on_delete=models.CASCADE)
        Role = models.ManyToManyField(Role)


    class Comment(models.Model):
        Content = models.TextField()
        MyUser = models.ForeignKey(MyUser, on_delete=models.CASCADE)


#2

حرف من پاسخ شما رو نمیده اما اگر هر دو FK هم دیگرو داشته باشند(اگر منظور شما اینه) اونوقت در بعضی دیتابیس ها دیگه هیچوقت نمیشه یکیشو پاک کرد، و قبلش باید حتما fk خالی بشه، کلا کار زیاد جالبی نیست.

این لینک رو خوندین؟
https://docs.djangoproject.com/en/2.1/topics/db/examples/one_to_one/

من گاهی بسته به نیاز برای one to one از unique constraint استفاده میکنم. آیا جنگو هم اینکارو میکنه؟ پاسخ با شما


#3

طبق اون لینک یک کلید خارجی با خاصیت کلید اصلی به مدل اضافه میشه . منم همین کاررو برای دو مدل که با MyUser رابطه یک به یک دارند انجام دادم :

class PhoneNumber(models.Model):
    Number = models.IntegerField()
    MyUser = models.ForeignKey(
        MyUser, on_delete=models.CASCADE, primary_key=True)

class Profile(models.Model):
    ImagePath = models.CharField(max_length=100)
    MyUser = models.ForeignKey(
        MyUser, on_delete=models.CASCADE, primary_key=True)

اون چیزی که به دست میده همون یک به یک هست اما اگر هر یک از این دو مدل خودشون با مدل دیگری رابطه یک به یک داشته باشند اون روش جواب نمیده. چون یک مدل تو جنگو تاجایی که میدونم نمیتونه دو فیلد کلید داشته باشه .
مثلا فکر کنید هر PhoneNumber علاوه بر MyUser با مدل دیگری مثل SimCarSerialNumber رابطه یک به یک داشته باشه مثل :

    class PhoneNumber(models.Model):
        Number = models.IntegerField()
        MyUser = models.ForeignKey(
            MyUser, on_delete=models.CASCADE, primary_key=True)
        SimCardSerialNumber = models.ForeignKey(
            SimCardSerialNumber, on_delete=models.CASCADE, primary_key=True)

یعنی باید دوتا فیلد کلید داشته باشه که نمیشه . بنابراین نمیتونیم تو این موارد ابطه یک به یک خالص داشته باشیم و فقط میتونیم به صورت صوری از روش های دیگه مثل unique constraint استفاده کنیم که منطقا درسته ولی تو نمودارهای ERD یه چیز دیگه ای نشون میده .


#4

حرف منم روی احتمال خطا در طراحی بود وقتی در استفاده از fk زیاده روی بشه، الان مشکل حل شده؟ ای کاش schema رو میزاشتین که من مجبور نباشم جنگو نصب کنم :laughing: آخه خیلی وقته از جنگو استفاده نکردم


#5

الان با این مدل هام مشکل حل شده ولی میگم برای حالتی که تو یک مدل بیشتر از یک رابطه یک به یک داشته باشیم مشکل پیش میاد و باید از روش های صوری استفاده کنیم . اینم schema :


#6

نمیشه گفت روش صوری، در اصل روش مناسبتر روش اصلی تریه☺️