invalid literal for int() with base 10: when using foreignkey - python

I'm trying to create a private chat with channels, I'm encountering an issue when passing an username to the url.
invalid literal for int() with base 10: 'username'
This error probably occurs because I'm using a ForeignKey because everything worked well using a ChatField and I want to know how I can resolve this issue.
models.py :
class Room(models.Model):
gig = models.ForeignKey(Gig, null=True)
creator = models.ForeignKey(User, related_name='creator', null=True)
views.py
def new_room(request):
try:
#get the submited product object
gig = Gig.objects.get(id=request.POST.get('inGig_id'))
except Gig.DoesNotExist:
return redirect('/')
creator = request.user
Room.objects.get_or_create(gig=gig, creator=creator)
return redirect(commenting_room, gig=gig.id, creator=creator)
def commenting_room(request, gig, creator):
room = Room.objects.get(gig=gig, creator=creator) #error occurs here
...
urls.py
url(r'^room/(?P<gig>\d+)/(?P<creator>\w+)/$', views.commenting_room, name='commenting_room_detail'),
Any suggestion on how I can resolve this problem ?

You should pass the creator id to .get and not the username text passed via the url, since creator is a ForeignKey field in Room:
def commenting_room(request, gig, creator):
creator_id = User.objects.get(username=creator).id
room = Room.objects.get(gig=gig, creator=creator_id)

Related

Using Django validators with admin - TypeError: "object of type 'int' has no len()"

so I have an eCommerce customer-facing app with a Django Admin interface. I want employees who will be using the admin to be able to create users. The problem is the custom regex validation I built in applies to the customer-facing side only, and when an employee wants to create a new user using the admin, my use of Django Validators throws an error when attempting to create the user.
I was wondering if (1) there was a way to reuse my UserManager class (inherited from models.Manager) which handles the customer-side validation, with Django admin also. If not, then (2) if I was to rely on Django Validators how could I clean up the code as to not throw errors like:
TypeError: "object of type 'int' has no len()
I've done a little homework trying to figure this out and found this thread: TypeError: object of type 'int' has no len() error assistance needed
This basically explains the error being thrown for this example is because it's trying to call len() on an int instead of a list. What I don't get is why don't I get this same error on the customer-facing side when a user signs himself up?
At any rate, I can't figure out how to implement the solution given how I set up my UserManager. I'm not using Django Forms and have tried fooling around with some of the clean methods, but am also trying not to repeat myself by reusing the validation I already wrote in the UserManager.
Here is my code, thanks for any help!
models.py
class UserManager(models.Manager):
def validation(self, postData, error_validation):
errors = {}
if error_validation == 'register':
if not NAME_REGEX.match(postData['first_name']):
errors['first_name'] = "First name can only contain letters."
if not NAME_REGEX.match(postData['last_name']):
errors['last_name'] = "Last name can only contain letters."
elif User.objects.filter(email=postData['email']):
errors['email'] = "Email already being used."
elif len(postData['password']) < 8:
errors['password'] = "Password must contain 8 or more characters."
elif not postData['password'] == postData['confirm_password']:
errors['password'] = "Both passwords must match!"
if error_validation == 'login':
user = User.objects.filter(email=postData['email'])
if not user or not bcrypt.checkpw(postData['password'].encode(), user[0].password.encode()):
errors['user_login'] = "Invalid credentials."
return errors
class User(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
dob = models.DateField()
address = models.CharField(max_length=100)
city = models.CharField(max_length=35)
state = models.CharField(max_length=2)
zipcode = models.IntegerField(validators=[MinLengthValidator(5), MaxLengthValidator(10)])
phone = models.IntegerField(validators=[MinLengthValidator(10), MaxLengthValidator(10)])
email = models.CharField(max_length=65)
password = models.CharField(max_length=255)
created_at = models.DateField(auto_now_add=True)
updated_at = models.DateField(auto_now=True)
objects = UserManager()
def __str__(self):
return self.email
You are using MinLengthValidator and MaxLengthValidator on the IntegerFields, which will try to apply len() function on the integers. That's why you got this kind of error. You can change your zipcode and phone attributes to CharField, or just remove the validators.
One thing to note is that CharField doesn't have a min_length attribute.
So just as an ill-advised alternative, instead of using Min/MaxLengthValidator, you can use Min/MaxValueValidator Min/MaxValueValidator. What's cool is you can subclass the validators to handle custom error messaging:
models.py
from django.core.validators import MinValueValidator, MaxValueValidator
class ZipcodeMaxValueValidator(MaxValueValidator):
message = ("AWWW YEA ERROR!!")
class User(models.Model):
zipcode = models.IntegerField(validators=[MinValueValidator(99999), ZipcodeMaxValueValidator(99999)]

Filtering Django User Choice Field use for a form

I am working on a hard django project and I am stuck again. I have a field in the userprofile which is called troop:
class UserProfile(models.Model):
scout_username = models.OneToOneField(User, on_delete=models.CASCADE)
Group_Choice = Groups.Scout_Groups()
troop = models.SlugField(max_length=27, choices=Group_Choice, default='None', blank=False)
date_of_birth = models.DateField(default=date.today)
def __str__(self):
return '%s'% (self.scout_username)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
Then I have a form which fills in data which is sent to my stData model. Within the form the user can choose to add details about another user. Except they can only add details to another user who has the same troop details.
forms.py
from django import forms
from leaders.models import stData
from django.contrib.auth.models import User
from accounts.models import UserProfileManager, UserProfile
st_username_list=[
(None, 'Choose a user'),
(user1, 'user1'),
(i, 'no progress'),
]
class BadgeForm(forms.ModelForm):
def set_user(self, user):
global st_username_list
troop = user.userprofile.troop
userprofile = UserProfile.objects.all()
selected_st = userprofile.filter(troop=troop)
for st in selected_st:
username = str(st.st_username)
st_username_list.append((username, username))
st_username = forms.ChoiceField(choices=st_username_list)
class Meta:
model = stData
fields = ('st_username', 'Pioneer_Badge', 'Explorer_Badge', 'Adventurer_Badge', 'Proficiency_Badge', 'Other_Badge')
Please note
In the example above I used a global variable. I understand this is far from desired. I have since removed it thanks to the explanation of the proper way to do the filter (found after the line break). I'm only keeping this for education reasons for others who may find they had similar problems.
I pass through the user within my views like this:
user = request.user
user_form_setting = BadgeForm.set_user(self, user)
models.py
from django.db import models
from django.contrib.auth.models import User
from accounts.st_badge_list import st_List
class stData(models.Model):
Pioneer_Choices = st_List.Target_Badges()
Blue_Choices = st_List.Target_Badges()
Black_Choices = st_List.Target_Badges()
Proficiency_Choices = st_List.Proficiency_Badges()
Other_Choice = st_List.Other_Badges()
Pioneer_Badge = models.CharField(max_length=16, choices=Pioneer_Choices, default='None', blank=True)
Blue_Star = models.CharField(max_length=16, choices=Blue_Choices, default='None', blank=True)
Black_Star = models.CharField(max_length=16, choices=Black_Choices, default='None', blank=True)
Proficiency_Badge = models.CharField(max_length=22, choices=Proficiency_Choices, default='None', blank=True)
Other_Badge = models.CharField(max_length=27, choices=Other_Choice, default='None', blank=True)
st_username = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateTimeField(auto_now=True)
print (User)
def __str__(self):
return '%s'% (self.st_username)
How would I go about having it so whatever user has the same troop details will appear within the st_username_list as a choice?
After researching and trying things with the code, I have been getting:
ValueError
Cannot assign "'user1'": "stData.st_username" must be a "User" instance.
I hope this is not too confusing.
Edit
Ok so I have found that I can filter the options for the st_username by doing
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['st_username'].queryset = UserProfile.objects.filter(troop='''user's troop''')
Problem update
My main issue now is that I am unable to pass through the user instance within the model. I have seen this question here. So I added this to my form's innit method:
self.user = kwargs.pop('user')
Yet when I try and use the user by going self.user I get the an unhelpful error KeyError saying user. The shell indicated this may be due to the self.user = kwargs.pop(user)
I believe this may be because I am not passing through the user. So when I call the form in my views, I tried form = BadgeForm(user=request.user) and got the same error.
my queryset looks like this now:
self.fields['scout_username'].queryset=UserProfile.objects.filter(troop=user.userprofile.troop)
Further Information:
To understand the problem better, I have passed through a set variable of the troop within the queryset. So in this case
self.fields['scout_username'].queryset=UserProfile.objects.filter(troop='BC')
Although now I get Error AttributeError:
'BadgeForm' object has no attribute 'name'
The shell links this with the formset from which I use the form with. The details I'm provided is:
line 435, in formset_factory
return type(form.__name__ + 'FormSet', (formset,), attrs)
I hope this makes more sense to you than to me! Any help would be greatly appreciated!
The final problem was within the use of the formset.
According to the docs, the proper way to add the kwargs is to do such:
BadgeFormsSet = formset_factory(BadgeForm)
formset = BadgeFormsSet(form_kwargs={'user': request.user})
Hope this helps any one else!

View articles by author in Django blog

I'm trying to create a view that allows one to see all blog posts written by a particular author. Here's the URL pattern I'm using:
url(r'^user/(?P<username>[\w-]+)/$', views.user_articles, name="user_articles"),
And here's my view:
def user_articles(request, username):
articles = Article.objects.filter(author=username).order_by('-date')
return render(request, "articles/article_list.html", {'articles': articles})
This is returning the error:
ValueError at /articles/user/danny/
invalid literal for int() with base 10: 'danny'
Editing to add model as well:
class Article(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(max_length=100, unique=True)
body = HTMLField('Body')
date = models.DateTimeField(auto_now_add=True)
thumb = models.ImageField(default="keys.jpg", blank=True)
author = models.ForeignKey(User, default=None)
danny is a valid username, and it should be a string, not an integer, so I'm not sure what's going wrong here. Any ideas?
Considering author, which is a ForeignKey to auth.User .
Your query should be
Article.objects.filter(author__username=username)
instead of ...Article.objects.filter(author=username)
Post your model but I assume the association between models, is a Foreign Key. So 'author' on your model Article is likely an ID and not a string. So instead of the username 'danny' try retrieving 'danny's ID.

Searching a Class by User ForeignKey

I have searched high and low and even in between and for some reason cannot come up with a clear answer...
I am using django1.9 and created this model:
class paymentInfo(models.Model):
"""
Model for storing payment info
- Username as ForeignKey from userToCard
- Store payment token
- Store last 4
- Store card/bank name
- Store bool value for Default method
"""
username = models.ForeignKey(User, db_column='username', on_delete=models.CASCADE)
token = models.CharField(max_length=10)
last_4 = models.IntegerField()
bank_name = models.CharField(max_length=50)
default = models.BooleanField(default=0)
class Meta: # meta class to define the table name
db_table = 'payment_methods'
verbose_name_plural = 'Payment Methods' # for the admin site display
ordering = ('username',)
def __str__(self):
# in __str__ you should return a value of type string
# so self.username changed to self.username.username
return self.username.username # value displayed in admin view
I have created some objects using some different usernames and want to filter out the paymentInfo objects by user.
When I store the object, the database stores the user pk under the username column instead of the actual username string. I am not sure why, but that is not my issue here.
My issue is when I am trying to filter out paymentInfo.objects using the username or the user pk. I cannot seem to filter it out and the error I normally get is thus: FieldError: Cannot resolve keyword 'username' into field. Choices are: bank_name, default, id, last_4, token
P.S. I am using MySQL
If I understood you right, you are trying to filter data by username from table User what is a foreign key. In this case, this should help
paymentInfo.objects.filter(username__name='John')
Thanks to the answers provided, I was able to work out a solution (mainly using #Aamir Adnan 's method.)
class paymentInfo(models.Model):
"""
Model for storing payment info
- Username as ForeignKey from userToCard
- Store payment token
- Store last 4
- Store card/bank name
- Store bool value for Default method
"""
user = models.ForeignKey(User, on_delete=models.CASCADE)
token = models.CharField(max_length=10)
last_4 = models.IntegerField()
bank_name = models.CharField(max_length=50)
default = models.BooleanField(default=0)
class Meta: # meta class to define the table name
db_table = 'payment_methods'
verbose_name_plural = 'Payment Methods' # for the admin site display
ordering = ('user',)
def __str__(self):
return self.user # value displayed in admin view
def __unicode__(self):
return '%s' % (self.user)
The new __unicode__ inside of my class was so that I did not receive this error anymore:
TypeError: coercing to Unicode: need string or buffer, User found

"invalid literal for int() with base 10:'username'"

I am making a web app with Django 1.7,python 2, but I am stuck in a part where I need that anonymous users can see the profiles of registered users (The URL is like this: "www.website.com/username) but I keep getting this error:
"invalid literal for int() with base 10:'andyjrr'"
where "andyjrr' is an username I pass it via URL.
This is my views.py:
def profiles(request, username):
context = RequestContext(request)
person = UserProfile.objects.get(user=username)
return render_to_response('detail.html',{'person':person},context)
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User,null=True,blank=True)
first_name = models.CharField(max_length=20,blank=True)
last_name = models.CharField(max_length=20,blank=True)
about_me = models.TextField(max_length=100,default='',blank=True)
experience = models.TextField(max_length=250,default='',blank=True)
offers = models.TextField(max_length=110,default='',blank=True)
TRACEBACK:
/home/andyjrr/Documents/jobby/users/views.py in profiles
person = UserProfile.objects.get(user=username)
I'm going to guess that the user field in the UserProfile model is a ForeignKey/OneToOne to auth.User.
If it is, then you'll need to modify your filter to join on the actually username of the auth.User model.
person = UserProfile.objects.get(user__username=username)

Categories