[英]How to save a random item returned from QuerySet. Django, Python
I am trying to save the returned item from QuerySet, so that later it will display all the saved items in the next template. 我正在尝试保存QuerySet中返回的项目,以便稍后它将在下一个模板中显示所有已保存的项目。 But I do not know how to go about it? 但是我不知道该怎么办?
1.) how to send the 'shot' to the database correctly?? 1.)如何将“快照”正确发送到数据库?
My models.py 我的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)
My views.py 我的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 forms.py
from django import forms
from .models import UserDecision
class UserDecisionForm(forms.ModelForm):
class Meta:
model = UserDecision
fields = ('decision',)
UPDATE UPDATE
Short version: try decision.relation = [shot]
简短版:尝试decision.relation = [shot]
Long version: 长版:
decision.relation
will return a related manager instance ; decision.relation
将返回相关的经理实例 ; a manager much like the one that <model>.objects
returns except that it manages all the records that are related to instance decision
. 一个类似于<model>.objects
返回的管理器,除了它管理与实例decision
相关的所有记录外。
The caveat is that decision.relation
is actually a data descriptor , a special attribute of an object (here: decision
) that allows some neat little tricks upon accessing ( __get__
) or changing ( __set__
) the attribute: 需要说明的是decision.relation
实际上是一个数据描述符 ,一个对象(这里的特殊属性decision
),允许一些巧妙的小把戏在访问( __get__
)或改变( __set__
)的属性:
Upon accessing the attribute relation
, you are provided with the aforementioned manager instance through the descriptor's __get__
method. 访问属性relation
,将通过描述符的__get__
方法为您提供上述管理器实例。
When setting the attribute (which you do with decision.relation = some_variable
) the descriptor uses its __set__
method which looks like this: 设置属性时(使用__set__
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)
So when you write decision.relation = shot
, thereby calling the above __set__
method, the descriptor will create the right manager for that relation and then call set(shot)
on it. 因此,当您编写__set__
decision.relation = shot
从而调用上面的__set__
方法时,描述符将为该关系创建正确的管理器,然后在其上调用set(shot)
。
Finally, set()
is expecting an iterable of model instances, but you only gave it a single model instance by itself. 最后, set()
期望模型实例具有可迭代性,但是您只给了它一个模型实例。
I'm not quite sure if this will actually answer your question, but I didnt want to add long comment to the opening post and answers are more lucid when it comes to explaining code. 我不确定这是否会真正回答您的问题,但是我不想在开篇文章中添加冗长的注释,并且在解释代码时答案更加清晰。
values()
will return a queryset of dictionaries representations of the objects in a query. values()
将返回查询中对象的字典表示形式的查询集。 You can use these dictionaries to make identical copies of those objects. 您可以使用这些词典为这些对象制作相同的副本。
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})
It is not clear what you are doing with those copies on the next view. 在下一个视图中,您不清楚这些副本正在做什么。 If you only want to display a copied object to avoid anyone actually making changes to the original and are then discarding the copies again once you leave the view (so as to not end up with a table full of copies), it would be better to change the template/use a simple form to only display the data of the original in the first place. 如果您只想显示一个复制的对象,以避免任何人实际对原始对象进行更改,然后在离开视图后又再次丢弃这些副本(以免最终得到一个充满副本的表),则最好更改模板/使用简单形式仅首先显示原始数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.