Home > Software engineering >  How to make 1:N orm? use prefetch_related?
How to make 1:N orm? use prefetch_related?

Time:12-10

template.html

                                        {% for portfolioList in portfolio_list %}
                                        <div >
                                            <div >
                                                <i ></i>
                                            </div>
                                            <div >
                                                <div >
                                                    <div >
                                                        <ul >
                                                            <li><a  href="{% url 'MyPortfolioUpdate' post_id=portfolioList.idx %}" role="button"> <i ></i> </a></li>
                                                            <li><a href="#"><i ></i></a></li>
                                                        </ul>
                                                    </div>
                                                    <span >{{portfolioList.start_date|date:"Y년 m월"}} ~ {{portfolioList.end_date|date:"Y년 m월"}}</span>
                                                    <h6 >{{portfolioList.subject}}</h6>
                                                    <span>-{{portfolioList.client_name}}</span>
                                                    <p >{{portfolioList.content|linebreaksbr}}</p>
                                                    <div >
                                                        {% for portfolioImgList in portfolio_img_list %}
                                                            {% if portfolioImgList.portfolio_idx.idx == portfolioList.idx %}
                                                            <div >
                                                                <img  src="{{portfolioImgList.file.url}}" alt="" >
                                                            </div>
                                                            {% endif %}
                                                        {% endfor %}
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                        {% endfor %}

view.py

q = Q()
        q &= Q(user_idx = request.user.id)
        portfolio_list =  UserPortfolio.objects.filter(q).order_by('-idx')

        q = Q()
        q &= Q(portfolio_idx__user_idx = request.user.id)
        portfolio_img_list = UserPortfolioFile.objects.filter(q).order_by('-idx')

        return render(request, 'account/setting/portfolio_list.html', {"portfolio_list":portfolio_list, "portfolio_img_list":portfolio_img_list}

model.py

class UserPortfolio(models.Model):
    idx = models.AutoField(primary_key=True)
    user_idx = models.ForeignKey(
        User,
        db_column='user_idx',
        on_delete=models.CASCADE
  )
    subject = models.CharField(max_length=255)
    client_name = models.CharField(max_length=255)
    client_service = models.CharField(max_length=255)
    client_category = models.CharField(max_length=255)
    start_date = models.DateTimeField()
    end_date = models.DateTimeField()
    content = models.TextField()
    write_date = models.DateTimeField(auto_now = True)
    update_date = models.DateTimeField(auto_now = True)
    is_file = models.CharField(max_length=1)

    class Meta:
        managed = False
        db_table = 'account_user_portfolio'

def portfolio_upload_to(instance, filename):
    nowDate = datetime.now().strftime("%Y/%m/%d")
    return '/'.join([str(instance.portfolio_idx.user_idx), instance.folder , nowDate, filename])

class UserPortfolioFile(models.Model):
    idx = models.AutoField(primary_key=True)
    portfolio_idx = models.ForeignKey(
        UserPortfolio,
        db_column='portfolio_idx',
        on_delete=models.CASCADE
  )
    folder = 'portfolio'
    file = models.ImageField(upload_to=portfolio_upload_to)

    class Meta:
        managed = False
        db_table = 'account_user_portfolio_file'

This is result. enter image description here

I want to use join orm in view.py. not like this. used 'if' in template.py

How can I do this? And I tried use join sql. but It was not worked.

I used prefetch_related this. but Its result was same as now.

And I think This is maybe good. doesn't?

Please answer something and thanks to every one

CodePudding user response:

You can enumerate with .userportfoliofile_set.all:

{% for portfolioImgList in portfolioList.userportfoliofile_set.all %}
    …
{% endfor %}

this will make a query to only retrieve the UserPortfolioFiles related to the portfolioList object.

In the view you can work with .prefetch_related(…) [Django-doc] to fetch all related items with one query, so:

def some_view(request):
    portfolio_list = UserPortfolio.objects.filter(
        user_idx=request.user.id
    ).prefetch_related('userportfoliofile_set').order_by('-idx')

    return render(request, 'account/setting/portfolio_list.html', {'portfolio_list':portfolio_list})
  • Related