Westagram # 2. Follow

์ด์ง€ํ›ˆยท2021๋…„ 7์›” 5์ผ
0

westagram

๋ชฉ๋ก ๋ณด๊ธฐ
2/3
post-thumbnail

related_name๊ณผ _set

class Account(models.Model):
    name            = models.CharField(max_length=50)
    nickname        = models.CharField(max_length=50)
    phone_number    = models.CharField(max_length=50, unique=True)
    password        = models.CharField(max_length=200)
    email           = models.EmailField(max_length=200, unique=True)

    class Meta:
        db_table = "accounts"

class Posting(models.Model):
    user = models.ForeignKey(Account, on_delete=models.CASCADE)
    post = models.CharField(max_length=50)
    content = models.CharField(max_length=50)
    created_at = models.DateTimeField(auto_now_add=True)
    # updated_at = models.DateTimeField(auto_now=True)
    img_url = models.URLField(max_length=200)

    class Meta:
        db_table = "postings"

Posting์€ Account๋ฅผ ์ •์ฐธ์กฐํ•˜๋ฏ€๋กœ ์†์„ฑ์œผ๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ๋ฐ, Account ๊ฐ์ฒด๋Š” Posting ๊ฐ์ฒด๋ฅผ ์—ญ์ฐธ์กฐํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๋ฐ”๋กœ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด๋•Œ [class_name]_set์„ ์‚ฌ์šฉํ•ด์„œ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์ด ๋•Œ _set ๋Œ€์‹ ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด related_name์ธ๋ฐ, ์—ญ์ฐธ์กฐ ๋Œ€์ƒ์ธ ๊ฐ์ฒด๋ฅผ ๋ถ€๋ฅผ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

์‚ฌ์‹ค related_name ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ƒ์— ์ถ”๊ฐ€๋˜๋Š” ์†์„ฑ์€ ์•„๋‹ˆ๊ณ  ForeignKey ๋กœ ์„ค์ •๋˜์–ด์ง€๋Š” Accunt๋ชจ๋ธ์—์„œ Posting ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์†์„ฑ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

๊ทธ๋Ÿฌ๋‹ˆ๊นŒ _set์„ ์“ฐ๋“  related_name์„ ์“ฐ๋“  ์‚ฌ์‹ค ๋น„์Šทํ•˜๋‹ค. ํ•˜์ง€๋งŒ ์–ธ์ œ๋‚˜ ๊ทธ๋ ‡๋“ฏ ์˜ˆ์™ธ๊ฐ€ ์žˆ๋Š” ๋ฒ•. ๐Ÿ˜ณ

class Follow(models.Model):
    following   = models.ForeignKey(Account, max_length=7000, on_delete=models.CASCADE, related_name="following")
    follower    = models.ForeignKey(Account, max_length=7000, on_delete=models.CASCADE, related_name="follower")

    class Meta:
        db_table = "follows"

๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ชจ๋ธ ๋‘ ๊ฐœ ์ด์ƒ์˜ FKํ‚ค๊ฐ€ ๊ฒน์น  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ์ด๋ฆ„์ด ๊ฒน์น  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ related_name์„ ๋ช…์‹œํ•ด์ค˜์„œ ์ปดํ“จํ„ฐ๊ฐ€ ํ—ท๊ฐˆ๋ฆฌ์ง€ ์•Š๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.

์ด๋•Œ๋Š” ํ•„์ˆ˜์ ์œผ๋กœ related_name์„ ์‚ฌ์šฉํ•ด์ค˜์•ผํ•œ๋‹ค.

Account์—์„œ Follow ๊ฐ์ฒด๋ฅผ ์—ญ์ฐธ์กฐํ•  ๋•Œ, Account ๊ฐ์ฒด๋ฅผ ์ •์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ following๊ณผ follower 2๊ฐœ์ด๋‹ค. _set๋งŒ์œผ๋กœ๋Š” ์ž์‹ ์„ ๋ฐ”๋ผ๋ณด๋Š” ๋‘ ์†์„ฑ ์ค‘ ์–ด๋–ค ์†์„ฑ์— ์ ‘๊ทผํ•ด์•ผํ•  ์ง€ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ฒ˜์Œ์—๋Š” ๊ทธ๋ƒฅ ํ•„๋“œ๋ช…์„ ๋˜‘๊ฐ™์ด ์ ์–ด์ฃผ๋ฉด ๋˜๋Š”๊ฑฐ ์•„๋‹ˆ์•ผ? ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์—ˆ๋‹ค. ๊ทผ๋ฐ ํ•„๋“œ๋ช…๊ณผ ๋˜‘๊ฐ™์ด ์ ์–ด์ฃผ๋ฉด ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค.

follower    = models.ForeignKey(Account, max_length=7000, on_delete=models.CASCADE, related_name="follower")

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑ์‹œ ํ•ด๋‹น follower์˜ Follow๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ, follower.follower.all() ์ฒ˜๋Ÿผ ๊ฐ€์ ธ์™€ ๋ฒ„๋ฆฐ๋‹ค.

๋”ฐ๋ผ์„œ related_name์„ follwering์œผ๋กœ ์จ์ค˜์•ผํ•œ๋‹ค. ๊ทธ๋Ÿผ follower.following.all ์ด๋ฏ€๋กœ ์กฐ๊ธˆ ๋” ์•Œ๊ธฐ ์‰ฌ์›Œ์ง€๋Š” ORM์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

  • foreign key๋กœ ์—ฐ๊ฒฐ์‹œ์ผœ ๋†“์€ class์— related_name = following์ด๋ผ๊ณ  ์ ์œผ๋ฉด follow.following์ด ์ƒ๊ธฐ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ฐธ์กฐํ•˜๋Š” Account(๋‚˜์˜ user ๋ชจ๋ธ๋ช…) ๋ชจ๋ธ์— ์ƒ๊ฒจ๋ฒ„๋ฆฐ๋‹ค.

  • ์ฐธ์กฐํ•ด์ค€ ๊ฐ์ฒด ์ž…์žฅ์—์„œ ์ƒ๊ฐํ•ด์„œ related_name์„ ์ž‘์„ฑํ•˜์ž!

์ˆ˜์ •

class Follow(models.Model):
    following   = models.ForeignKey(Account, max_length=7000, on_delete=models.CASCADE, related_name="follower")
    follower    = models.ForeignKey(Account, max_length=7000, on_delete=models.CASCADE, related_name="following")

    class Meta:
        db_table = "follows"

manytomanyfield์™€ foreign key ์†์„ฑ์ฐจ์ด

ManyToMany์™€ Foreign key์˜ ์ฐจ์ด๋Š” ์ค‘๊ฐ„ํ…Œ์ด๋ธ”์„ ๋งŒ๋“œ๋ƒ ์•ˆ๋งŒ๋“œ๋ƒ์˜ ์ฐจ์ด์ด๋‹ค.

1 to Many(1๋Œ€๋‹ค)- Foreign key Field

  1. 1๋Œ€ ๋‹ค์— ํ•ด๋‹นํ•˜๋Š” Foreign key๋Š” ๊ด€๊ณ„ ์„ค์ •์ด 1๊ฐœ๋งŒ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์—ฐ๊ฒฐ๋œ ๋ชจ๋ธ ์ค‘ ์–ด๋Š ๊ณณ์— ์ถ”๊ฐ€๋˜๋Š๋ƒ์— ๋”ฐ๋ผ ์˜๋ฏธ๊ฐ€ ๋‹ฌ๋ผ์ง„๋‹ค.

  2. ์ž๋™ ์ƒ์„ฑ์ด ์•„๋‹ˆ๋ผ ๋‚ด๊ฐ€ ์ค‘๊ฐ„ ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค์–ด์„œ ๊ด€๋ฆฌํ•ด์•ผํ•œ๋‹ค.

  3. ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ํƒ€ ํ…Œ์ด๋ธ”๊ณผ์˜ ์ž‘์—…์„ ํ•˜๋ ค๋ฉด ์ค‘๊ฐ„ํ…Œ์ด๋ธ”์„ ๊ฑฐ์ณ ๊ฐ’์„ ๋„ฃ์–ด์ค˜์•ผํ•œ๋‹ค. ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ๋„ ์ค‘๊ฐ„ ํ…Œ์ด๋ธ”์˜ ๊ฐ’๋งŒ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.(๋ฌด์กฐ๊ฑด ์ง•๊ฒ€๋‹ค๋ฆฌ๋กœ ์ด์šฉํ•ด์•ผํ•œ๋‹ค๋Š” ๋œป)

  4. ํ•˜์ง€๋งŒ ์‹ค๋ฌด์—์„œ๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋‹ค๊ฐ€ ์ถ”๊ฐ€๋˜๋Š” ์†์„ฑ์ด๋‚˜ ๊ฐ’์ด ์žˆ๊ธฐ ๋งˆ๋ จ์ด๋ฏ€๋กœ ์ง์ ‘ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ๋”ฐ๋ผ์„œ ์ค‘๊ฐ„ํ…Œ์ด๋ธ”์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

Many To Many(๋‹ค๋Œ€๋‹ค) - ManyToManyField

  1. ManyToMany ์†์„ฑ์€ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ด€๊ณ„์˜ ์ˆ˜์— ์ œํ•œ์ด ์—†๋‹ค.

  2. ๋‘ ๋ชจ๋ธ์˜ ๊ด€๊ณ„๋Š” ์ž๋™์ƒ์„ฑ๋˜๋Š” Intermediate Table ์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๋ชจ๋ธ์˜ ํ…Œ์ด๋ธ”์—๋Š” ํ•„๋“œ๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค.

  3. ์ค‘๊ฐ„ ํ…Œ์ด๋ธ”์ด ์—†์œผ๋ฏ€๋กœ ๋ฐ”๋กœ ์—ฐ๊ฒฐ๊ฐ’์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Œ.


model.py, views.py

# ํŒ”๋กœ์šฐ model.py
class Follow(models.Model):
    following   = models.ForeignKey(Account, max_length=7000, on_delete=models.CASCADE, related_name="following")
    follower    = models.ForeignKey(Account, max_length=7000, on_delete=models.CASCADE, related_name="follower")

    class Meta:
        db_table = "follows"
        
# ํŒ”๋กœ์šฐ views.py
class FollowView(View):
    def post(self, request):
        try:
            data = json.loads(request.body)
            if Follow.objects.filter(following=data['following'], follower=data['follower']).exists():
                Follow.objects.filter(following=data['following'], follower=data['follower']).delete()
            Follow.objects.create(
                following_id = data['following'],
                follower_id = data['follower']
            )
            return JsonResponse({"MESSAGE":"SUCCESS"}, status=201)
        except KeyError:
            return JsonResponse({"MESSAGE":"KEY_ERROR"}, status=400)

    def get(self, request):
        try:
            follows = Follow.objects.all()

            result=[]
            for follow in follows:
                result.append({
                    'following' : follow.following_id,
                    'follower'  : follow.follower_id
                })
            return JsonResponse({"RESULT":result, "MESSAGE":"SUCCESS"}, status=200)
        except KeyError:
            return JsonResponse({"MESSAGE":"ERROR"}, status=400)

models.py์—์„œ ํ•˜๋‚˜์˜ class์— ๋Œ€ํ•ด ๋™์ผํ•œ class ๊ฐ์ฒด๊ฐ€ ๋‘๋ฒˆ FK๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— related_name์„ ์ด์šฉํ–ˆ๋‹ค.

views.py์—์„œ๋Š” follow ๊ฐ์ฒด์— filter๋ฅผ ๊ฑธ๋Ÿฌ ํŒ”๋กœ์œ™๊ณผ ํŒ”๋กœ์šฐ ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๊ณ  ๋‘๋ฒˆ ํŒ”๋กœ์šฐ ํ•  ์ˆ˜ ์—†๊ฒŒ ํ•ด๋‹น Account๊ฐ€ followingํ˜น์€ followerํ•˜๋Š” instance๋ฅผ deleteํ•˜๋Š” ๊ฒƒ์ด๋‹ค.


์•„์‰ฌ์šด ์ 

unfollow ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ–ˆ์œผ๋ฉด ์ข‹์•˜์„ ๊ฒƒ ๊ฐ™๋‹ค.

์• ์ดˆ์— ํŒ”๋กœ์œ™ํ•˜์ง€ ์•Š์€ ๊ด€๊ณ„์— ๋Œ€ํ•ด์„œ ์–ด๋–ป๊ฒŒ ํ•  ๊ฒƒ์ธ์ง€ ์ƒ๊ฐํ•˜์ง€ ์•Š์•˜๋‹ค.


์ฐธ๊ณ  ์ž๋ฃŒ

related_name๊ณผ _set
https://swarf00.github.io/2019/09/06/associate-user.html

https://velog.io/@brighten_the_way/Django%EC%99%80-Reverse-relations%EA%B3%BC-Relatedname

ManyToMany vs Foreingkey
https://brunch.co.kr/@ddangdol/1

https://devbruce.github.io/django/dj-14-model_many+to+many/

์ค‘๊ฐ„ํ…Œ์ด๋ธ”์„ ๋งŒ๋“œ๋Š” ์ด์œ 
https://fierycoding.tistory.com/66?category=983255

related_name ์ด๋ฆ„์„ ๋ฌด์—‡์œผ๋กœ ์“ธ ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•œ ํฌ์ŠคํŒ…
https://fabl1106.github.io/django/2019/05/27/Django-26.-%EC%9E%A5%EA%B3%A0-related_name-%EC%84%A4%EC%A0%95%EB%B0%A9%EB%B2%95.html

profile
๊พธ์ค€ํ•˜๊ฒŒ ๐ŸŒ

0๊ฐœ์˜ ๋Œ“๊ธ€