Как я могу использовать два типа модели набора запросов переопределить метод сохранения? - PullRequest
0 голосов
/ 02 апреля 2020

Я хочу спросить вас, отправляю ли я статью с featured = True, тогда старый featured = true переносится в featured = false набор запросов. я просто хочу два [:2] значения в featured = true queryset. вот пример того, что я хочу есть две статьи в featured = true queryset, которые я хочу, чтобы вторая статья автоматически обновлялась до featured = false при создании новой статьи.

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

Вот запрос база данных с print(featured_articles.count()), фотография списка статей в admin , и шаблон .

models.py

    class ArticleQuerySet(models.Manager):
        def get_queryset(self):
            return super(ArticleQuerySet,self).get_queryset().filter(status=True)


    class Article(models.Model):
       title = models.CharField(max_length=100)
       author = models.ForeignKey(
       User, on_delete=models.CASCADE, blank=True, null=True)
       thumbnail = models.ImageField(default='def.jpg',
                                upload_to='article/thumbnails')
       timestamp = models.DateTimeField(auto_now_add=True)
       content = RichTextUploadingField(blank=True)
       featured = models.BooleanField(default=False)
       status = models.BooleanField(default=True)
       tags = TaggableManager()
       objects = models.Manager()
       status_objects = ArticleQuerySet()

        def __str__(self):
            return self.title

        class Meta:
            ordering = ['-timestamp']

     # i also try this method
        def save(self, *args, **kwargs):
            if self.featured == True:
                Article.objects.filter(pk__in=(Article.objects.filter(featured=True,
                 ).values_list('pk',flat=True)[:2])).update(featured=False)
                self.featured = True
            super(Article, self).save(*args, **kwargs)

views.py

from django.shortcuts import render
from .models import Article


def index(request):
    featured_articles = Article.status_objects.filter(tags__exact='1', featured=True)[:2]
    regular_articles = Article.status_objects.filter(tags__exact='1').exclude(pk__in=featured_articles)

    context = {
        'featured': featured_articles,
        'regular': regular_articles,
    }

    return render(request, 'news/index.html', context)

index. html

    <!--post header-->
    <div class="post-head">
        <h2 class="title"> Article </h2>
    </div>
    <!-- post body -->
    <div class="post-body">
        <div class="">
            <!-- item one -->
            <div class="item">
                <div class="row">
                    <div class="col-sm-6 main-post-inner bord-right">
                        {% for nat in featured %}
                        <article>
                            <figure>
                                <a href="{% url 'news-detail' pk=nat.pk %}"><img src="{{ nat.thumbnail.url }}"
                                        height="242" width="345" alt="" class="img-responsive"></a>
                            </figure>
                            <div class="post-info">
                                <h3><a href="#">{{ nat.title }}</a>
                                </h3>
                                <span>
                                    <i class="ti-timer"></i>
                                    {{ nat.timestamp | timesince }}
                                </span>
                                <p></p>
                            </div>
                        </article>
                        {% endfor %}
                    </div>
                    <div class="col-sm-6">
                        <div class="news-list">
                            {% for nat in regular %}
                            <div class="news-list-item">
                                <div class="img-wrapper">
                                    <a href="{% url 'news-detail' pk=nat.pk %}" class="thumb">
                                        <img src="{{ nat.thumbnail.url }}" alt="" class="img-responsive">
                                        <div class="link-icon">
                                            <i class="fa fa-camera"></i>
                                        </div>
                                    </a>
                                </div>
                                <div class="post-info-2">
                                    <h5><a href="{% url 'news-detail' pk=nat.pk %}" class="title">{{ nat.title }}</a>
                                    </h5>
                                    <i class="ti-timer"></i> {{ nat.timestamp | timesince }}
                                </div>
                            </div>
                            {% endfor %}
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Ответы [ 2 ]

1 голос
/ 02 апреля 2020

Ваш код выглядит нормально, но стандартный способ сделать это - пометить все как есть, как есть, без пометки предыдущих статей как featured=False:

views.py

def articles(self):
    featured_articles = Article.status_objects.filter(tags__exact='1', featured=True)[:2]
    regular_articles = Article.status_objects.filter(tags__exact='1').exclude(pk__in=featured_articles)
    ...

Обратите внимание, что .exclude(featured=True) отсутствует в наборе запросов regular_articles. Старые избранные статьи автоматически переносятся в этот набор запросов.

Некоторые преимущества этого подхода:

  1. Нет необходимости вести список избранных статей
  2. вести список ранее показанных статей
  3. Вы не сталкиваетесь с условиями гонки, когда добавляются / добавляются несколько статей
  4. Вы не мешаете базе данных обновлениями
  5. Ваш код легче поддерживать и читать
  6. Обновление отдельной статьи не имеет побочных эффектов (например, когда вы обновляете статью, вы точно знаете, что обновляете только эту статью, ничего больше)

Как говорится, бывают случаи, когда вы действительно хотите пометить их как featured=false, но, если у вас нет веских причин для этого, обычно лучше сделать вещи проще.

0 голосов
/ 05 апреля 2020

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

class featured (models.Model):
    featured=models.OneToOneField(Article, related_name='featured', on_delete=models.CASCADE )

создайте столько статей, сколько хотите. Предположим, вы хотите только две избранные статьи, а затем создайте только две записи.

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

...