An unexpected keyword argument python - python

I'm trying to implement a simple function to like a post.
I have 4 models defined using Google App Engine; User, Blogpost, Like, Comments
below is the snippets:
class LikePost(db.Model):
user = db.ReferenceProperty(User)
blogpost = db.ReferenceProperty(Blogpost)
date = db.DateTimeProperty(auto_now_add = True)
class Comment(db.Model):
user = db.ReferenceProperty(User)
blogpost = db.ReferenceProperty(Blogpost)
content = db.TextProperty(required = True)
date = db.DateTimeProperty(auto_now_add = True)
I tried to call the method to like a post using below:
class LikePost(Handler):
def get(self,post_id):
blogpost = self.get_blogpost(post_id)
user = self.get_user_object()
if blogpost and user:
like = LikePost(user = user, blogpost = blogpost)
like.put()
self.redirect('/%s' % post_id)
else:
self.redirect('/login')
The reference to the method is as follow:
def get_user_object(self):
cookie = self.request.cookies.get('user_id')
if cookie:
user_id = check_secure_val(cookie)
if user_id:
user_id = cookie.split('|')[0]
key = db.Key.from_path('User', int(user_id))
user = db.get(key)
return user
def get_blogpost(self, post_id):
key = db.Key.from_path('Blogpost', int(post_id))
blogpost = db.get(key)
return blogpost
I got an error when trying to run the above :
__init__() got an unexpected keyword argument 'blogpost'
Anyone can explain what went wrong ?

You have defined your model as
class LikePost(db.Model):
Then you have defined your handler has
class LikePost(Handler):
Notice that they have the same name. So inside your get method what's in scope is your Handler subclass, which apparently does not expect a blogpost keyword argument to it's __init__ method. Simplest solution, rename one or the other or
from models import LikePost as LP
and use that

Related

get() returned more than one-- Django Restframework

I have a Django model which needs to have more than 1 images and more than 1 files (numbers may vary as per requirement), for which I adjusted my Admin Panel accordingly like this
models.py
class MasterIndividualMembers(models.Model):
individualmemberId = models.CharField(primary_key=True, max_length=100, default=1)
...
...
def __str__(self):
return self.firstname + " " + self.lastname
class IndividualMemberPhotos(models.Model):
individualmemberId = models.ForeignKey(MasterIndividualMembers, default=None,on_delete=models.CASCADE)
image = models.ImageField(upload_to="individualmemberphotos/")
class IndividualMemberCatalogue(models.Model):
individualmemberId = models.ForeignKey(MasterIndividualMembers, default=None,on_delete=models.CASCADE)
files = models.FileField(upload_to="individualmembercatalogue/")
admin.py
class IndividualMemberPhotosAdmin(admin.StackedInline):
model = IndividualMemberPhotos
class IndividualMemberCatalogueAdmin(admin.StackedInline):
model = IndividualMemberCatalogue
#admin.register(MasterIndividualMembers)
class MasterIndividualMembersAdmin(admin.ModelAdmin):
inlines = [IndividualMemberPhotosAdmin,IndividualMemberCatalogueAdmin]
class Meta:
model = MasterIndividualMembers
For the views I simply make a function to provide details of all the Images, Document and that User
views.py
#csrf_exempt
#api_view(['POST'])
#permission_classes([IsAuthenticated])
def get_individualmember(request):
if request.method == 'POST':
try:
individualmemberId = request.POST.get('individualmemberId')
result = {}
result['individualMemberDetails'] = json.loads(serializers.serialize('json', [MasterIndividualMembers.objects.get(individualmemberId=individualmemberId)]))
result['individualPhotoDetails'] = json.loads(serializers.serialize('json', IndividualMemberPhotos.objects.filter(individualmemberId__individualmemberId = individualmemberId)))
result['individualCatalogueDetails'] = json.loads(serializers.serialize('json', IndividualMemberCatalogue.objects.filter(individualmemberId__individualmemberId = individualmemberId)))
except Exception as e:
return HttpResponseServerError(e)
Problem: While fetching the details for any individual member, it throws an error get() returned more than one IndividualMemberPhotos -- it returned 2!, which is expected to have more than 1 objects.
How can I make the Restframework to provide me details of all image object together.
Instead of using get() which strictly returns a single element, use filter() which returns 0 or more elements.
As documented in https://docs.djangoproject.com/en/3.2/topics/db/queries/#retrieving-a-single-object-with-get
filter() will always give you a QuerySet, even if only a single object
matches the query - in this case, it will be a QuerySet containing a
single element.
If you know there is only one object that matches your query, you can
use the get() method on a Manager which returns the object directly:
The behavior you are experiencing is actually documented here https://docs.djangoproject.com/en/3.2/ref/models/querysets/#django.db.models.query.QuerySet.get
If get() finds more than one object, it raises a
Model.MultipleObjectsReturned exception:

Unexpected keyword argument when working with several objects

I'm trying to work with severals objects to achieve an action.
My models.py
class LogBook(models.Model):
name = models.CharField()
class LogMessage(models.Model):
logbook = models.ForeignKey(LogBook, on_delete=models.CASCADE)
class LogDone(models.Model):
logmessage = models.ForeignKey(LogMessage)
done_status = models.BooleanField(default=False)
My view :
def logmessage_done(request, logmessage_id, log_id, token ):
log = get_object_or_404(LogBook, pk=log_id)
logmessages = LogMessage.objects.filter(logbook=log)
logdone = LogDone.objects.get_or_create(logmessage=logmessages)
logdone.done_status = True
logdone.update()
My url :
"done/<int:logmessage_id>/<int:log_id>/<str:token>"
What I want to achieve :
I want to change the status of the logdone object which is link to the logmessage object but I am not sure I have access object correctly.
What error I have :
The QuerySet value for an exact lookup must be limited to one result using slicing.
Change your view like this:
def logmessage_done(request, logmessage_id, log_id, token ):
log = get_object_or_404(LogBook, pk=log_id)
logmessages = LogMessage.objects.filter(logbook=log)
for log_message in logmessages:
LogDone.objects.update_or_create(logmessage=log_message,defaults={"done_status": True})
Here , log returns a single object with id . logmessages returns a queryset with logbook = the log returned in first query. Have to use update_or_create method

NameError in Django simple search

I have a simple search in my Django project. I want to search through documents using their type and part of factory info in addition to search by name.
Here is my models.py:
class Docs(models.Model):
Date = models.DateField(default=date.today)
Name = models.CharField(max_length=50)
Type = models.ForeignKey(DocTypes)
Part = models.ForeignKey(Parts)
Link = models.FileField(upload_to='Docs/%Y/%m/%d')
class Parts(models.Model):
Name = models.CharField(max_length=50)
def __str__(self):
return str(self.Name)
class DocTypes(models.Model):
Type = models.CharField(max_length=50)
def __str__(self):
return str(self.Type)
My forms.py:
class DocsSearchForm(ModelForm):
class Meta:
model = Docs
fields = [ 'Name', 'Type', 'Part']
And this is part of my views.py, if no search was done then all documents are given
def showdocs(request):
if request.method == 'POST':
form = DocsSearchForm(request.POST)
documents = Docs.objects.filter(Name__contains=request.POST['Name']|
Type==request.POST['Type']|
Part==request.POST['Part'])
else:
form = DocsSearchForm()
documents = Docs.objects.all()
return render(
request,
'showdocs.html',
{'documents': documents, 'form':form}
So, the problem is the following: if I try to use a search then I have
NameError at /showdocs
name 'Type' is not defined.
POST values are:Part '1', Name 'Example', Type '1'.
If I delete
Type==request.POST['Type']|
Part==request.POST['Part']
then search by name works well. So I have a guess that problem is about searching by foreign key values, but have no ideas more. Will appreciate any help.
Try replacing the line with this
Docs.objects.filter(Name__contains=request.POST['Name'],
Type=request.POST['Type'],
Part=request.POST['Part']
)
It seems you have misunderstood the syntax. I don't know why you are trying to use | operator here.
That's not how Django filters work. You can't | them because they are not actually expressions, just keyword arguments. In this case, correct syntax would be:
Docs.objects.filter(
Name__contains=request.POST['Name'],
Type_Type=request.POST['Type'],
Part_Name=request.POST['Part'],
)`

How to call in instance of Resource in Django Tastypie.?

Here is my tastypie code snippet.
I have a Resource and in post_list method , an instance of Mysample is getting created there.
I want to call a method of Mysample Instance , Please help me how to do that,
please find the comment in code where I need to call the method of Mysample instance
class MysampleResource(ModelResource):
intfeild1 = fields.IntegerField('intfeild1_id', null=True)
intfeild2 = fields.IntegerField('intfeild1_id')
class Meta:
always_return_data = True
queryset = Mysample.objects.all()
allowed_methods = ['get','post','put','delete',]
authentication = SessionAuthentication()
authorization = MysampleAuthorization()
def post_list(self, request, **kwargs):
result = super(MysampleResource, self).post_list(request, **kwargs)
#here I want to call a method of Mysample Instance.
return result
Please help me , I'm begginer, so could you please give suggestion on which method to override and where should I need to do that.
You just need to add your method in your resource:
def test_method(self,param*):
#Do your stuff
return result
and within post_list you can call it like:
self.test_method(param*)
Note: The method declaration include 2 params but in python "self" is passed on as an implicit param so that when you call your method you don't pass on the self object.
= could be more than just one parameter in that case use "," in order to separate them.
If we apply all the previous concepts your code should look like:
class MysampleResource(ModelResource):
intfeild1 = fields.IntegerField('intfeild1_id', null=True)
intfeild2 = fields.IntegerField('intfeild1_id')
class Meta:
always_return_data = True
queryset = Mysample.objects.all()
allowed_methods = ['get','post','put','delete',]
authentication = SessionAuthentication()
authorization = MysampleAuthorization()
def post_list(self, request, **kwargs):
result = super(MysampleResource, self).post_list(request, **kwargs)
#Let's say that you want to pass resquest as your param to your method
method_result=self.test_method(request)
return result
def test_method(self,request):
#Do your stuff
return result

Populate a WTForms form object with a datetime.date

I'm cooking up a crud interface for an object representing a bill, as in the water bill, the electric bill, etc.
I'm using sqlalchemy to handle the data, wtforms to handle the forms, and flask to serve it.
Here's what my route looks like that serves the form for editing an existing bill:
#app.route('/edit_bill/<int:bill_id>', methods = ['GET'])
def edit_bill(bill_id):
s = Session()
bill = s.query(Bill).filter_by(id=bill_id).first()
form = BillForm(obj=Bill)
return render_template('edit_bill.html', form = form)
Using wtforms, I pass the bill object to the BillForm constructor, ensuring that the data representing the bill to be edited it populated to the form.
This is where it chokes. Here's the exception:
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Bill.date_due has an attribute 'strftime'
Now, I've dipped into the python shell and queried up a bill to make sure that date_due has a datetime.date object on it, which is does. I use Jinja to build my front end, so I've looked into creating a template filter, but I don't know how that would work with wtforms, and it looks like sqlalchemy is the one choking anyway.
So what it do? I'm pretty confident I just need to figure out how to turn that datetime.date object into a string, but I'm not sure how to go about that.
Halp. Thanks!
Edit: Here's the BillForm class:
class BillForm(Form):
id = HiddenField()
name = TextField(u'Name:', [validators.required()])
pay_to = TextField(u'Pay To:',[validators.required()])
date_due = DateField(u'Date Due:',[validators.required()])
amount_due = IntegerField(u'Amount Due:', [validators.required()])
date_late = DateField(u'Late After:',[validators.required()])
amount_late = IntegerField(u'Late Amount:', [validators.required()])
date_termination = DateField(u'Termination Date:',[validators.required()])
And mapping class, too:
class Bill(Base):
__tablename__ = 'bills'
id = Column(Integer, primary_key=True)
name = Column(String)
pay_to = Column(String)
amount_due = Column(Integer)
date_due = Column(Date)
amount_late = Column(Integer)
date_late = Column(Date)
date_termination = Column(Date)
def __init__(self, name, pay_to, amount_due, date_due, amount_late, date_late, date_termination):
self.name = name
self.pay_to = pay_to
self.amount_due = amount_due
self.date_due = date_due
self.amount_late = amount_late
self.date_late = date_late
self.date_termination = date_termination
def __repr__(self):
return "<Bill ('%s', '%s', '%s', '%s')>" % (self.name, self.pay_to, self.amount_due, self.date_due)
Ah it took me some time to figure out where you went wrong, but think I found it out. Here's your code:
#app.route('/edit_bill/<int:bill_id>', methods = ['GET'])
def edit_bill(bill_id):
s = Session()
bill = s.query(Bill).filter_by(id=bill_id).first()
form = BillForm(obj=Bill)
return render_template('edit_bill.html', form = form)
Now, if pass a class as the obj kwarg in BillForm, the form gets populated with all kinds of strange objects. For example, if I replicate what you did and inspect form.date_due.data, it says it is an <sqlalchemy.orm.attributes.InstrumentedAttribute at 0x277b2d0> object. Like what is stated in the error message, this object does not have a strftime attribute.
So, your error is in line 5 of the code you presented. If you want to populate the form with the details of the bill object you retrieved in line 4, replace line 5 with form = BillForm(obj=bill). As you can see, the 'subtle' difference is the lowercase b in bill. I replicated your code and am convinced should fix the problem.
If you're interested, this is how I normally make edit views.
#app.route('/edit_bill/<int:bill_id>', methods = ['GET', 'POST'])
def edit_bill(bill_id):
s = Session()
bill = s.query(Bill).filter_by(id=bill_id).first()
form = BillForm(request.form, obj=bill)
if request.method == 'POST' and form.validate():
form.populate_obj(bill)
s.add(bill)
s.commit()
# Do some other stuff, for example set a flash()
return render_template('edit_bill.html', form = form)
I haven't used SQLAlchemy for a while so I might have made a couple of mistakes there. Hope this helps! If this answers your question 'accept' the answer.

Categories

Resources