본문 바로가기
웹 개발 이야기/django

[django] Tag (manytomany)

by Gommin 2023. 5. 12.

models.py

class Tag(models.Model):
    pidx = models.ForeignKey('Program', related_name='tagpost', on_delete=models.CASCADE, db_column='pidx', verbose_name='프로그램', null=True)
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Program(models.Model):
    yn_choices = (
        ('Y', 'Y'),
        ('N', 'N'),
    )

    pcate = models.ForeignKey('BoardCategory', related_name='pcpost', on_delete=models.CASCADE, db_column='pcate', verbose_name='카테고리', null=True)
    psubject = models.CharField(max_length=255, verbose_name='프로그램명')
    pspeaker = models.CharField(blank=True, max_length=255, verbose_name='연사', null=True)
    psdatetime = models.DateTimeField(blank=True, max_length=30, verbose_name='시작일시', null=True)
    pedatetime = models.DateTimeField(blank=True, max_length=30, verbose_name='종료일시', null=True)
    plocate = models.CharField(max_length=255, verbose_name='장소')
    pcontent = QuillField()
    pimg = models.ImageField(blank=True, upload_to='laboratory/program/%Y/%m/%d', verbose_name='대표 이미지')
    tag_set = models.ManyToManyField('Tag', blank=True)
    plink = models.CharField(blank=True, max_length=255, verbose_name='신청 링크', null=True)
    chk_end = models.CharField(blank=True, max_length=3, choices=yn_choices, default='N', verbose_name='마감')
    created_at = models.DateTimeField(blank=True, auto_now_add=True, verbose_name='등록일시')
    updated_at = models.DateTimeField(blank=True, auto_now=True, verbose_name='수정일시')

    def __str__(self):
        return f'{self.pcate} | ({self.psubject})'

    def photo_tag(self, post):
        if post.pimg:
            return mark_safe(f'<img src="{post.pimg.url}" alt="" style="width: 75px;" />')
        return None

    def extract_tag_list(self):
        tag_list = []
        for tag_name in re.findall(r'#([a-zA-Z\dㄱ-힣]+)', self.caption):
            tag, _ = Tag.objects.get_or_create(name=tag_name)
            tag_list.append(tag)
        return tag_list

views.py

srd = Program.objects.get(id=pk)
pt_tag = request.POST.get('pt_tag')

# tag_set 삭제
    tagsall = srd.tag_set.all()
    if tagsall:
        tagsall.delete()

    if pt_tag:
        tagjson = json.loads(pt_tag)
        for tg in tagjson:
            # tag_set 추가 및 등록
            tag, _ = Tag.objects.get_or_create(name=tg['value'])
            srd.tag_set.add(tag)

template.html

<link rel="stylesheet" type="text/css" href="//modulabs.dmonster.co.kr/lib/tagify/tagify.css?v=20230413_03">
<script type="text/javascript" src="//modulabs.dmonster.co.kr/lib/tagify/jQuery.tagify.min.js?v=20230413_03"></script>

<div class="form-group row">
    <label for="pt_tag" class="col-sm-2 col-form-label">태그 <b class="text-danger">*</b></label>
    <div class="col-sm-10">
        <!--<tags class="tagify  form-control form-control-sm mb-2" tabindex="-1">
            <tag title="ai" contenteditable="false" spellcheck="false" tabindex="-1"
                 class="tagify__tag tagify&#45;&#45;noAnim" value="ai">
                <x title="" class="tagify__tag__removeBtn" role="button"
                   aria-label="remove tag"></x>
                <div><span class="tagify__tag-text">ai</span></div>
            </tag>
            <span contenteditable="" tabindex="0" data-placeholder="" aria-placeholder="" class="tagify__input" role="textbox" aria-autocomplete="both" aria-multiline="false"></span>
        </tags>-->
        <input type="text" name="pt_tag" id="pt_tag" value="{{tags}}" class="form-control form-control-sm mb-2" tabindex="-1">
        <small class="form-text text-muted">* ',(콤마)' 로 구분하여 입력바랍니다. 10개까지 가능합니다.</small>
        <script>
        $(document).ready(function () {
            $('#pt_tag').tagify({
                duplicates : true,
                maxTags: 10,
                trim:true,
            });
        });
        </script>
    </div>
</div>

댓글