Reputation: 2177
I am trying to save the returned item from QuerySet, so that later it will display all the saved items in the next template. But I do not know how to go about it?
1.) how to send the 'shot' to the database correctly??
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)
My 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',)
Upvotes: 0
Views: 105
Reputation: 2921
UPDATE
Short version: try decision.relation = [shot]
Long version:
decision.relation
will return a related manager instance; a manager much like the one that <model>.objects
returns except that it manages all the records that are related to instance 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:
Upon accessing the attribute relation
, you are provided with the aforementioned manager instance through the descriptor's __get__
method.
When setting the attribute (which you do with decision.relation = some_variable
) the descriptor uses its __set__
method which looks like this:
# 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.
Finally, set()
is expecting an iterable of model instances, but you only gave it a single model instance by itself.
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. 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.
Upvotes: 1