Как сохранить случайный элемент, возвращенный из QuerySet. Джанго, Питон - PullRequest
0 голосов
/ 03 ноября 2018

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

1.) Как правильно отправить «выстрел» в базу данных ??

My models.py

class City(models.Model):
    name = models.CharField(max_length=100)

class User(models.Model):
    name = models.CharField(max_length=100)
    city = models.ForeignKey(City, on_delete=models.CASCADE)

class UserDecision(models.Model):
    decision = models.BooleanField(default=False)
    relation = models.ManyToManyField(User)

Мои views.py

from django.shortcuts import render
from .models import User
from .forms import UserDecisionForm

def random_views(request):
    shot = User.objects.all().order_by('?')[:1]

    #Begining form here
    if request.method == "POST":
        form = UserDecisionForm(request.POST)
        if form.is_valid():
            decision = form.save(commit=False)
            decision.relation = shot #<--- how to pass this element to the database automatically. According to the result returned from the QuerySet query.
            decision.save()
    else:
        form = UserDecisionForm()

    # other elements
    context = {'shot': shot, 'form':form }
    return render(request, 'index.html', context)

forms.py

from django import forms

from .models import UserDecision

class UserDecisionForm(forms.ModelForm):
    class Meta:
        model = UserDecision
        fields = ('decision',)

1 Ответ

0 голосов
/ 04 ноября 2018

UPDATE

Короткая версия: попробуйте decision.relation = [shot]

Длинная версия:
decision.relation вернет связанный экземпляр диспетчера ; менеджер, очень похожий на тот, который возвращает <model>.objects, за исключением того, что он управляет всеми записями, связанными с экземпляром decision.
Предостережение заключается в том, что decision.relation на самом деле дескриптор данных , специальный атрибут объекта (здесь: decision), который допускает некоторые аккуратные трюки при доступе (__get__) или изменении (* 1020). *) атрибут:
Получив доступ к атрибуту relation, вы получаете вышеупомянутый экземпляр менеджера с помощью метода дескриптора __get__.

При установке атрибута (который вы делаете с decision.relation = some_variable) дескриптор использует свой метод __set__, который выглядит следующим образом:

# django.db.models.fields.related_descriptors.py: 518
def __set__(self, instance, value):
    """
    Set the related objects through the reverse relation.

    With the example above, when setting ``parent.children = children``:

    - ``self`` is the descriptor managing the ``children`` attribute
    - ``instance`` is the ``parent`` instance
    - ``value`` is the ``children`` sequence on the right of the equal sign
    """
    ...
    manager = self.__get__(instance)
    manager.set(value)

Поэтому, когда вы пишете decision.relation = shot, вызывая тем самым вышеуказанный метод __set__, дескриптор создаст правильного менеджера для этого отношения и затем вызовет set(shot) для него.
Наконец, set() ожидает повторяемых экземпляров модели, но вы дали ему только один экземпляр модели.


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

values() вернет набор запросов представлений словарей объектов в запросе. Вы можете использовать эти словари для создания идентичных копий этих объектов.

user_data = User.objects.order_by('?').values()[:1][0]
user_data[User._meta.pk.name] = None # We cannot use an existing pk for the copy
copied_user = User.objects.create(**user_data)
return render(request, 'index.html', {'shot':copied_user})

Не ясно, что вы делаете с этими копиями на следующем экране. Если вы хотите отобразить только скопированный объект, чтобы никто не вносил изменения в оригинал, а затем снова отбрасывает копии после того, как вы покинете представление (чтобы не получить таблицу, полную копий), было бы лучше изменить шаблон / использовать простую форму, чтобы отображать только данные оригинала.

...