When creating a model instance how to fill ManyToMany field? - python

I want to create model instance like this:
new_tweet = Tweet.objects.create(text = tweet_object.text, date = tweet_object.date, username = tweet_object.username, retweet = tweet_object.retweet.all(), is_ret = True)
It's all going well until this: retweet = tweet_object.retweet.all(). It returns this error: 'retweet' is an invalid keyword argument for this function
This is a ManyToMany field. So how to fill this field when creating new model instance?
By the way tweet_object.retweet.all() is consisted of many retweetobjects.
EDIT:
Model:
class Tweet(models.Model):
text = models.CharField(max_length=140)
date = models.DateTimeField(auto_now_add=True)
username = models.CharField(max_length=140)
favourite = models.ManyToManyField(Favourite)
retweet = models.ManyToManyField(Retweet)
replies = models.ManyToManyField('Tweet')
is_ret = models.BooleanField(default=False)
def __unicode__(self):
return self.username
And tweet_object, which is just another tweet:
tweet_object = Tweet.objects.get(id=tweet_id)

I think you should create Tweet object first and next you can create relations with retweets.
More about information you can find here: https://docs.djangoproject.com/en/dev/topics/db/examples/many_to_many/
It's very simply:
tweet_object = Tweet.objects.get(id=tweet_id)
new_tweet = Tweet.objects.create(text = tweet_object.text, date = tweet_object.date, username = tweet_object.username, is_ret = True)
for retweet in tweet_object.retweet.all():
new_tweet.retweet.add(retweet)
new_tweet.save()

Related

ValueError: Field 'id' when filter model data based on user

How do I return objects based on the user who made the model entry? Here is what I've tried below but I get an error:
models.py
class Csv(models.Model):
file_name = models.FileField(upload_to='csvs', max_length = 100)
public = models.BooleanField(default = False)
user = models.ForeignKey(User, on_delete = models.CASCADE, null = True)
name = models.CharField(max_length = 100)
library = models.CharField(max_length = 100, null = True)
def __str__(self):
return "File id: {}".format(self.id)
query
from .models import Csv
x = Csv.objects.get(user = "site_manager")
returns the error in the description
from .models import Csv
x = Csv.objects.get(library = "example library")
returns a file from the database as intended. Why does this not work when I search based on username?
The reason is that field user is a foreign key, so the search criteria must indicate which column in model User is the one that must match the search criteria:
from .models import Csv
x = Csv.objects.get(user__username = "site_manager")
In this case, double underscore notation indicates that we are referencing field username in instance of model User pointed by field user.

Using related_name to return queryset not working in django?

Here I am working with two models.Both models have ForeignKey relation to the User model. Here I wanted to query staffs, is_reviewed_by and sent_by and I tried like this. When I do filter it returns the queryset but when I used related_name to query then it throws AttributeError.
How can i do this?
`Exception Value:
'Leave' object has no attribute 'reviewed_by
models.py
class Leave(models.Model):
staff = models.ForeignKey(get_user_model(),on_delete=models.CASCADE,related_name='staff_leave')
organization = models.ForeignKey(Organization,on_delete=models.CASCADE,related_name='staff_leave')
sub = models.CharField(max_length=300)
msg = models.TextField()
start_day = models.DateField()
end_day = models.DateField()
is_reviewed_by = models.ForeignKey(get_user_model(),on_delete=models.CASCADE,related_name='reviewed_by',blank=True,null=True)
class LeaveReply(models.Model):
staff = models.ForeignKey(get_user_model(),on_delete=models.CASCADE,related_name='leave_status')
leave = models.ForeignKey(Leave,on_delete=models.CASCADE,related_name='leave_status')
sub = models.CharField(max_length=300,blank=True,null=True)
msg = models.TextField(blank=True,null=True)
sent_on = models.DateTimeField(auto_now_add=True)
sent_by = models.ForeignKey(get_user_model(),on_delete=models.CASCADE,related_name='sent_by')
views.py
def leave_detail(request, pk):
leave = get_object_or_404(Leave, pk=pk)
reviewers = leave.reviewed_by.all() # not working
staffs = leave.staff_leave.all() # does not works
staffs = Leave.objects.filter(staff=leave.staff) # this works
reviewers = Leave.objects.filter(is_reviewed_by=leave.is_reviewed_by) # works
reply_sender = LeaveReply.objects.filter(sent_by=leave.is_reviewed_by) #works
reply_sender = leave.sent_by.all() # doesn't works
You're a bit confused. There is nothing to do with related_name here.
You have a Leave object. As the error says, Leave items don't have reviewed_by, sent_by or staff_leave attributes. They have is_reviewed_by and staff; and the only sent_by object is on the LeaveReply object.
Edited answer
models:
class Leave(models.Model):
staff = models.ForeignKey(get_user_model(),on_delete=models.CASCADE,related_name='staff_leave')
organization = models.ForeignKey(Organization,on_delete=models.CASCADE,related_name='staff_leave')
is_reviewed_by = models.ForeignKey(get_user_model(),on_delete=models.CASCADE,related_name='reviewed_by',blank=True,null=True)
I think this model is for Leave details of employee.
Not working code:
reviewers = leave.reviewed_by.all() # not working
staffs = leave.staff_leave.all() # does not works
And this is for, staff who is taking leave and a person who reviewed the leave application. Both fields are related to User model. If we have instance of Leave model (i.e. leave = get_object_or_404(Leave, pk=pk)), then we can get these two by this:
staffs = leave.staff # for person who will be on leave
reviewers = leave.is_reviewed_by # for the person who reviewed the leave
Extra
If we have a User instance (user = get_object_or_404(User, pk=pk)), and we want to know how many leaves he has taken, then we can use related name:
no_of_leaves_itaken = user.staff_leave.all()
or how many leaves he has reviewed:
no_of_leaves_reviewed = user.staff_leave.all()

django - prepending a field in the query set that doesn't exist in the model

I have a model that reads from a pre-existing university database. The username is stored as the students id. I'm not able to add a new column to the database in a save or I could use a save function in my model.
class Student(models.Model):
student_id = models.IntegerField(db_column = 'Student_ID', primary_key = True)
statusid = models.IntegerField(db_column = 'StatusID')
fname = models.CharField(db_column = 'Student_First_Name', max_length = 35)
lname = models.CharField(db_column = 'Student_Last_Name_Formatted' , max_length = 40)
class Meta:
managed = False
db_table = '[Student]'
What i'm trying to do is take the username in a query and match it up with another field that is umich.edu/student_id as a primary key.
I'm defining the request in one function as:
def user_list(request):
student = Student.objects.all()
passing in the argument for students to my template with a POST to the form.
In my next view that gets posted
def criteria(request):
user = request.POST.get('student_id')
print(user)
student = CourseCriteria.objects.get(universitystudentid = request.POST.get('student_id'))
My print/post of user is coming through correctly as the student id, but I need to prepend umich.edu/ to the student_id in the queryset. How can I accomplish this without being able to add that field to my model?
I am not sure to understand your problem, I suppose that it is not as simple as:
def criteria(request):
user = request.POST.get('student_id')
student = CourseCriteria.objects.get(universitystudentid='umich.edu/%s'%user)

Assigning an author to an entity during its creation

I am doing Udacity's Web Dev Course with Google Appengine and Python.
I would like to know how I could assign to a created entity, its own author.
For example, I have two ndb.Models kinds:
class User(ndb.Model):
username = ndb.StringProperty(required = True)
bio = ndb.TextProperty(required = True)
password = ndb.StringProperty(required = True)
email = ndb.StringProperty()
created = ndb.DateTimeProperty(auto_now_add = True)
class Blog(ndb.Model):
title = ndb.StringProperty(required = True)
body = ndb.TextProperty(required = True)
created = ndb.DateTimeProperty(auto_now_add = True)
When a Blog entity is created by a logged-in user, its own author (User entity) should also be identified with it.
Ultimately, I would like to display a blog's post with its author's information (for example, the author's bio)
How can this be achieved?
Your Blog class should include a property to store the key of the user who wrote it:
author = ndb.KeyProperty(required = True)
You can then set this property when you create a Blog instance:
blog = Blog(title="title", body="body", author=user.key)
For optimization, if you know the logged in user's ndb.Key, and you don't need the user entity itself, you would pass that directly, instead of needing to fetch the user first.
assert isinstance(user_key, ndb.Key)
blog = Blog(title="title", body="body", author=user_key)
In full:
class User(ndb.Model):
username = ndb.StringProperty(required = True)
password = ndb.StringProperty(required = True)
email = ndb.StringProperty()
created = ndb.DateTimeProperty(auto_now_add = True)
class Blog(ndb.Model):
title = ndb.StringProperty(required = True)
body = ndb.TextProperty(required = True)
created = ndb.DateTimeProperty(auto_now_add = True)
author = ndb.KeyProperty(required = True)
def new_blog(author):
"""Creates a new blog post for the given author, which may be a ndb.Key or User instance"""
if isinstance(author, User):
author_key = author.key
elif isinstance(author, ndb.Key):
assert author.kind() == User._get_kind() # verifies the provided ndb.Key is the correct kind.
author_key = author
blog = Blog(title="title", body="body", author=author_key)
return blog
You may get bonus points if you standardize the beginning of new_blog to a utility function.

Embedded Documents issue with MongoEngine

I am using MongoDB with Flask-MongoEngine as my ORM component to my web app.
I have structured the User document schema like so:
from ..core import db
class UserComics(db.EmbeddedDocument):
favorites = db.SortedListField(db.StringField(), default=None)
class UserSettings(db.EmbeddedDocument):
display_favs = db.BooleanField(default=False)
default_cal = db.StringField(default=None)
show_publishers = db.ListField(db.StringField(), default=None)
class UserTokens(db.EmbeddedDocument):
refresh_token = db.StringField(default=None)
access_token = db.StringField(default=None)
expire_time = db.StringField(default=None)
class User(db.Document, UserMixin):
# Save User document to this collection
meta = {'collection': 'users_test'}
userid = db.StringField()
full_name = db.StringField()
first_name = db.StringField()
last_name = db.StringField()
gender = db.StringField()
birthday = db.StringField()
email = db.EmailField()
friends = db.ListField(db.StringField())
date_creation = db.DateTimeField()
last_login = db.DateTimeField()
favorites = db.EmbeddedDocumentField(UserComics)
settings = db.EmbeddedDocumentField(UserSettings)
tokens = db.EmbeddedDocumentField(UserTokens)
However, When creating a new user like this (I have left out lines...):
def create_new_user(resp):
newUser = User()
....
newUser.settings.default_cal = resp['calendar']
....
newUser.save()
return
I run into this error:
AttributeError: 'NoneType' object has no attribute 'default_cal'
It seems to me that I am not using MongoEngines Embedded documents correctly but I do not know where I am going wrong.
Any help would be greatly appreciated!
Well you just have to create an embedded document object of the particular class, and then use it with the main document class, like so:
new_user = User()
user_settings = UserSettings()
user_settings.default_cal = resp['calendar']
new_user.settings = user_settings
# more stuff
new_user.save()
Note: Creating a new object only for the main document, does not automatically create the corresponding embedded document object(s), but while reading data ofcourse the case is different.
Edit:
As tbicr mentions below, we can also do this:
settings = db.EmbeddedDocumentField(UserSettings, default=UserSettings)
while declaring the field, that way we won't need to create the object as given in the first example.

Categories

Resources