its showing me that "book() got an unexpected keyword argument 'name'" - django

its showing me that "book() got an unexpected keyword argument 'name' "
my views.py
def book(request):
if request.method=='POST':
name=request.POST['name']
email=request.POST['email']
password=request.POST['password']
type=request.POST['r']
ticket_from=request.POST['ticket_from']
ticket_to=request.POST["ticket_to"]
dept_date=request.POST['dept_date']
ret_date=request.POST['ret_date']
adults=request.POST['adults']
children=request.POST['childern']
tck=book(name=name,email=email,password=password,type=type,ticket_from=ticket_from,ticket_to=ticket_to,dept_date=dept_date,ret_date=ret_date,adults=adults,children=children)
tck.save()
return HttpResponse("Booked")
else:
return render(request,"book.html",)
models.py
# Create your models here.
class book(models.Model):
name=models.CharField(max_length=100)
email=models.EmailField(max_length=100)
password=models.CharField(max_length=100)
type=models.CharField(max_length=100)
ticket_to=models.CharField(max_length=100)
ticket_from=models.CharField(max_length=100)
dept_date=models.DateField()
ret_date=models.DateField()
adults=models.IntegerField()
children=models.IntegerField()
i dont know what is this error and how can i solve this
plzz help me with this

Always use Capital letters for class names. Your code actually is trying to use view's function instead of model's class. You have used exactly the same name, which is very confusing.
Change this:
class book(models.Model):
...
To this:
class Book(models.Model):
...
And always create new object with first Capital letter:
def book(request):
if request.method=='POST':
...
tck = Book(name=name, email=email, ...)
tck.save()
return HttpResponse("Booked")
And for more complex class' names always start new word with another capital letter, in example:
class VeryOldBook(models.Model):
...
Read that for all the important rules: https://realpython.com/python-pep8/

views.py
def book(request):
if request.method=='POST':
name=request.POST['name']
email=request.POST['email']
password=request.POST['password']
type=request.POST['r']
ticket_from=request.POST['ticket_from']
ticket_to=request.POST["ticket_to"]
dept_date=request.POST['dept_date']
ret_date=request.POST['ret_date']
adults=request.POST['adults']
children=request.POST['childern']
tck=Book(name=name,email=email,password=password,type=type,ticket_from=ticket_from,ticket_to=ticket_to,dept_date=dept_date,ret_date=ret_date,adults=adults,children=children)
tck.save()
return HttpResponse("Booked")
else:
return render(request,"book.html",)
models.py
class Book(models.Model):
name=models.CharField(max_length=100)
email=models.EmailField(max_length=100)
password=models.CharField(max_length=100)
type=models.CharField(max_length=100)
ticket_to=models.CharField(max_length=100)
ticket_from=models.CharField(max_length=100)
dept_date=models.DateField()
ret_date=models.DateField()
adults=models.IntegerField()
children=models.IntegerField()
this should solve your problems

Related

'function' object has no attribute 'objects'

I am trying to get a query set which contains post based on usernames which are stored in model "FollowingProfiles". so models and corresponding views is as follows:-
from django.contrib.auth.models import User
class Profile(models.Model):
Follwers=models.IntegerField(default='0')
user=models.OneToOneField(User,on_delete=models.CASCADE,primary_key=True)
bio=models.TextField(max_length=120,blank=True)
location=models.CharField(max_length=30,blank=True)
birth_date=models.DateField(null=True,blank=True)
verified=models.BooleanField(default=False)
ProfilePic=models.ImageField(upload_to='UserAvatar',blank=True,null=True)
def __str__(self):
return self.user.username
#receiver(post_save,sender=User)
def update_user_profile(sender,instance,created,**kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
class FollowingProfiles(models.Model):
Profile=models.ForeignKey(Profile,on_delete=models.CASCADE)
ProfileName=models.CharField(max_length=120,blank=True,null=True)
def __str__(self):
return self.ProfileName
class post(models.Model):
Profile=models.ForeignKey(Profile,on_delete=models.CASCADE)
Picture=models.ImageField(upload_to='PostMedia',blank=True,null=True)
DatePosted=models.DateTimeField(default=timezone.now)
Content=models.TextField(blank=True,null=True)
def __str__(self):
return self.Profile.user.username
views.py
def feed(request):
if request.user.is_authenticated:
userprofile=FollowingProfiles.objects.filter(Profile__user=request.user)
for p in userprofile:
postuser=post.objects.filter(Profile__user__username=p.ProfileName)
usrpost+=postuser
return render(request,'feed/feed.html',{'usrpost':usrpost})
else:
return redirect('signup')
It produces following error:-
function' object has no attribute 'objects'
C:\Users\G COMTECH SYSTEM\django-projects\saporaapp\sapora\views.py in feed, line 45
line 45 is
postuser=post.objects.filter(Profile__user__username=p.ProfileName)
Seems like your post model is conflicting with some post declared as function.
What I suggest is to follow PEP8 in naming your Classes, function, variables and so on in order to avoid such cases.
In your particular case I would rename post model into Post as it's better to name Classes in CamelCase style.
But for fields your are using CamelCase, but it's better to use underscore:
Like that:
class Post(models.Model):
profile = models.ForeignKey(Profile,on_delete=models.CASCADE)
picture = models.ImageField(upload_to='PostMedia',blank=True,null=True)
date_posted = models.DateTimeField(default=timezone.now)
content = models.TextField(blank=True,null=True)
If you want to make it work fast find where post can be declared as a function in view.py file and rename it. If it's something imported you can change from mymodule import post to be import mymodule and then call function as mymodule.post
Also usrpost is not declared and here is a better solution without for loop:
userprofile_names=FollowingProfiles.objects.filter(Profile__user=request.user).values_list('ProfileName', flat=True)
usrpost=post.objects.filter(Profile__user__username__in=userprofile_names)
return render(request,'feed/feed.html',{'usrpost':usrpost})

How to call a function with context in django CB list view?

This is my view:
class viewbloglistview(LoginRequiredMixin,ListView):
model = Blog
paginate_by = 6
def get_template_names(self):
if True:
return ['blog/view_blogs.html']
else:
return ['blog/blog_list.html']
def get_queryset(self):
return Blog.objects.all().order_by('-blog_views')[:20]
def get_context_data(self, **kwargs):
context = super(viewbloglistview, self).get_context_data(**kwargs)
context['categories_list'] = categories.objects.all()
return context
This is my function in models.py file:
def categories_count(self):
categories_count = categories.objects.annotate(blog_count=Count('blogs')).values_list('Title','blog_count')
return categories_count
I want call the function in my views with a context name to render the activity in my template..
Can anyone please help me out to solve this problem??
Thank you
This is a python problem, your question is unclear but based on what you said:
Case the function in in your model.py alone:
from . import model.py
// code
categories_count()
Case the function is a method in a class as it is shown on you code with the self parameter in it:
from . import model.py
// code
classname.categories_count()
Assuming that you have named your class as 'categories' (which should have been named as Category in the first place),
categories_count should have been in a manager as you are querying in a class level. Say you don't want a manager and want to keep the code inside the model, then you can use it as a class method.
#classmethod
def categories_count(cls):
return cls.objects.annotate(blog_count=Count('blogs')).values_list('Title','blog_count')
and in the views use it as
categories.categories_count()
Just remember that the regular methods with the 'self' argument like the one you have, should only be used when you are dealing with a single instance, not when you are accessing the class itself.

Django form empty numeric field clean validation

Im trying to validate in a django form if the user entered a numeric value on a field called "usd_value" using the clean method like this :
Form.py
class CostItemsForm(ModelForm):
def __init__(self, *args, **kwargs):
super(CostItemsForm, self).__init__(*args, **kwargs)
class Meta:
model = CostItems
fields = [
'group',
'description',
'usd_value',
'rer',
'pesos_value',
'supplier',
'position',
'observations',
'validity_date',
]
def clean_usd_value(self):
if self.cleaned_data.get('usd_value'):
try:
return int(self.cleaned_data['usd_value'].strip())
except ValueError:
raise ValidationError("usd_value must be numeric")
return 0
But is not working, i mean, if i leave the field empty or enter a text value there, alert doesn't activate at all and i got error (obviously) if i try to save the form. Any help ??
Here's my views.py
class CostItemInsert(View):
template_name='cost_control_app/home.html'
def post(self, request, *args, **kwargs):
if request.user.has_perm('cost_control_app.add_costitems'):
form_insert = CostItemsForm(request.POST)
if form_insert.is_valid():
form_save = form_insert.save(commit = False)
form_save.save(force_insert = True)
messages.success(request, "cost item created")
#return HttpResponseRedirect(reverse('cost_control_app:cost_item'))
else:
messages.error(request, "couldn't save the record")
return render(request, self.template_name,{
"form_cost_item":form_insert,
})
else:
messages.error(request, "you have no perrmissions to this action")
form_cost_item = CostItemsForm()
return render(request, self.template_name,{
"form_cost_item":form_cost_item,
})
I think your function name is wrong. Your field name is usd_value but your function is clean_usd. Change it to clean_usd_value and it should work.
Check Django doc section The clean_<fieldname>().
Edit
Also your return value for your clean method is wrong. Check the django doc example, you need to return the cleaned_data not 0:
def clean_usd_value(self):
cleaned_data = self.cleaned_data.get('usd_value'):
try:
int(cleaned_data)
except ValueError:
raise ValidationError("usd_value must be numeric")
return cleaned_data
But on a second throught, you might not even need the clean_usd_value method at all, django form field should have the default validation for you. Remove entirely the clean_usd_value method and see if it works.
I don't think you need custom validation for this. In fact, I think the builtin validation for django.forms.FloatField is going to be better than what you have.
Based on your error, I'm assuming that the form isn't using a FloatField for usd_value, and that's a bit odd. Make sure that your CostItems model has usd_value defined as a django.db.models.FloatField like below.
from django.db import models
class CostItems(models.Model):
usd_value = models.FloatField()
# other stuff
Once you do this, your CostItemsForm should automatically use django.forms.FloatField for usd_value. If it doesn't, you can always define this field explicitly.
from django import forms
class CostItemsForm(ModelForm):
usd_value = forms.FloatField(required=True)
class Meta:
model = CostItems
fields = [
'group',
'description',
'usd_value',
'rer',
'pesos_value',
'supplier',
'position',
'observations',
'validity_date',
]
If neither of these suggestions is helpful, please post your CostItems model.

Create method in forms.Form

My questions is, can I create methods in a form?
I want to create a method in a UserChangeForm it should control some things.
And how can I call this method then in the save() if commit?
In the forms.form I must create a save() too?
I tried this:
class UserChangeForm(forms.Form):
#fields for the form
def create_club_contact(self):
user = super(UserChangeForm, self).save(commit=False)
if information is None:
#create clubcontact
else:
#update clubcontact
return clubcontact
def clean_password2(self):
#check password
return password2
def save(self):
data = self.cleaned_data
user = TennisClub(link=data['link'], name=data['name'])
user.save()
contact = self.create_club_contact()
user.club_contact = contact
user.save()
On this way I'm always getting this Error
'super' object has no attribute 'save'
I think the forms.Form needs a save() method, but I don't know, how to do it right.
In the docs, I have not seen such a example.
Thanks for helping.
class MyForm(forms.Form):
def __init__(self):
self.member = False
# example of a method with return statement
def my_method(self):
return something
# example for a void method, no return value
def another_method(self):
self.member = True
def save(self):
my_variable = self.my_method()
self.another_method()
# continue with your logic
EDIT:
I think you don't have the problem with creating methods and calling them. The above is probably clear to you. But it seems that you have another problem, but you can't question it right.
Your form inherits from Form. The parent class Form has a method save() and you want to override it.
Put this in the end of your method save() and try again:
return super(UserChangeForm, self).save()

Django - ForeignKey field initial value definition in Admin

I have a Person model, which has a ForeignKey field to itself, called mother.
When the user goes to the 'add' admin form, I want to define an initial value for mother, in case there is a GET('mother') parameter, or leave it blank, in case there is not.
I have actually 2 questions:
How to access request inside ModelAdmin?
How to define initial value for a ForeignKey field?
In models.py:
class Person(models.Model):
name=models.CharField()
mother=models.ForeignKey('self')
In admin.py:
class PersonAdminForm(forms.ModelForm):
class Meta:
model = Person
class PersonAdmin(admin.ModelAdmin):
mother = request.GET.get('mother','') #don`t know how to access request
if mother != '':
form = PersonAdminForm
form.initial={'mother':Person.objects.get(id=mother)}
Well, this ain't working. Even if I only try to define a hardcoded initial value, it doesn`t work.
What am I doing wrong?
PS.: Of course, I may be asking the wrong questions, so I appreciate any help that solves the problem.
My solution:
class PersonAdmin(admin.ModelAdmin):
form = PersonAdminForm
# ...
def get_form(self, request, obj=None, *args, **kwargs):
form = super(PersonAdmin, self).get_form(request, *args, **kwargs)
# Initial values
form.base_fields['mother'].initial = None
if obj and obj.mother:
form.base_fields['mother'].initial = obj.mother
return form
Oh, it happens to be a lot easier than I thought.
If you pass a GET parameter with the name of the field as key to a Django`s add form, the GET parameters value will be set as initial value for that field.
In my case, I just needed to redirect to
localhost/admin/my_app/person/add/?&mother=< id >
There was no need for manipulating admin or anything.
Try overriding the get_form() method on ModelAdmin:
class PersonAdmin(admin.ModelAdmin):
form = PersonAdminForm
def get_form(self, request, *args, **kwargs):
form = super(PersonAdmin, self).get_form(request, *args, **kwargs)
mother = request.GET.get('mother', None)
if mother:
form.initial = {'mother': Person.objects.get(id=mother)}
return form