Retrieving user details using username from extended User Model in Django - python

I'm trying to retrieve the details of a user using the username test from an extended User model in Django. But I am unable to do it. It's giving me the error:
ValueError at / invalid literal for int() with base 10: 'test'
Following is my code:
models.py
class DocchainUser(models.Model):
docchainuser_name = models.OneToOneField(User, on_delete = models.CASCADE, default='x')
address = models.CharField(max_length=64,unique=True)
def __str__(self):
return self.address
views.py
def my_users(request):
if request.method == 'POST':
username = request.POST.get('username')
user = authenticate(username=username)
if user:
if user.is_authenticated:
signBool = signatureAuth(username)
if signBool == 'AUTHENTICATED':
login(request, user, backend=settings.AUTHENTICATION_BACKENDS[0])
return HttpResponseRedirect('/dashboard')
....
And the signatureAuth() now:
def signatureAuth(username):
userModel = DocchainUser.objects.filter(docchainuser_name=username)
address = userModel.address
print(address)
...
I'm retrieving the user details using username: test in signatureAuth() method. test is already present in my User as well as DocchainUser model.

You don't have an extended user model, you have a separate model with a one-to-one relation to User. So in order to query that model by username, you need to follow the relationship.
userModel = DocchainUser.objects.filter(docchainuser_name__username=username)
Note, one of the reasons you struggled here is that your OneToOneField is probably misnamed; the relationship is with the entire model, not the username; you should call it just docchainuser.
(Also note, your if user.is_authenticated is pointless; that just checks that the user is an instance of User rather than AnonymousUser, which you know it is because you just explicitly retrieved it from the User model.)

Related

User Follower model on Django. Cannot use add() on a ManyToManyField which specifies an intermediary model. Use accounts.Contact's Manager instead

I am new to Django, Please forgive any silly mistakes in code or logic,
Intro: I am trying to create a user follower model in Django. Where users can follow and unfollow other users on the sites
Error: I have made the models for my follow/unfollow I have also made the views I am getting this error
AttributeError at /accounts/admin/follow/
Cannot use add() on a ManyToManyField which specifies an intermediary model. Use accounts.Contact's Manager instead.
The obj.followers.add(user) is highlighted in the traceback as the origin of the error
Below are my models.py
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
city = models.CharField(max_length=100)
country = models.CharField(max_length=100)
def get_absolute_url(self):
return reverse('accounts:profile', kwargs={'username': self.user.username})
class Contact(models.Model):
user_from = models.ForeignKey(User, related_name='suppporter')
user_to = models.ForeignKey(User, related_name='leader')
def __str__(self):
return '{} follows {}'.format(self.user_from, self.user_to)
User.add_to_class('following',
models.ManyToManyField('self', through=Contact, related_name='followers', symmetrical=False))
I think the models.py may be good. The fault I believe is in my views.
Below is my view.py
class FollowToggle(LoginRequiredMixin, RedirectView):
def get_redirect_url(self, *args, **kwargs):
username = self.kwargs.get('username')
print(username + " This is the user who will be followed") # This prints correct
profile = get_object_or_404(Profile, user__username=username)
print(profile) # This prints correct
obj = get_object_or_404(User, username=username)
print(obj) # This prints correct
url_ = profile.get_absolute_url()
print(url_) # This prints correct
user = self.request.user
print(user) # This prints correct
if user.is_authenticated():
if user in obj.followers.all(): # I know this is the source of the error.
obj.followers.remove(user)
else:
obj.followers.add(user)
return url_
Below are the Urls.py just in case
url(r'^(?P<username>[-\w]+)/follow/$', views.FollowToggle.as_view(), name='follow'),
You cannot use add and remove method for manytomany relation defined through third model. From the docs:
Unlike normal many-to-many fields, you can’t use add(), create(), or set() to create relationships
Instead you should use Contact manager:
if user.is_authenticated():
if user in obj.followers.all(): # I know this is the source of the error.
Contact.objects.filter(user_to=obj, user_from=user).delete()
else:
Contact.objects.create(user_to=obj, user_from=user)
In Django 2.2 you can use add, remove and set methods (Docs)
You can also use add(), create(), or set() to create relationships, as long as your specify through_defaults for any required fields

Saving extended user model data from POST method API

I don't have any forms to get input from user only by using POSTMAN i have tested this.
I extend my default user model by OneToOneField
class Profile(models.Model):
user = models.OneToOneField(User, related_name='profile')
phone = models.CharField(max_length=15)
address = models.CharField(max_length=250)
and i implemented below method
def create_profile(sender, instance, **kwargs):
if kwargs["created"]:
user_profile = Profile(user=instance)
instance.profile.save()
post_save.connect(create_profile, sender=User)
so it creates a record for profile while any record gets inserted in user model.
For example If i have made any API call like localhost:8000/signup with POST method data like
username: abc, password: passkey123, phone: 9876543210 it save username and password in user model respective profile model created with user reference failed to update my phone number field.
I don't have any forms to get datas. Below is my view that routed from /signup
#api_view(['post'])
#authentication_classes([])
#permission_classes([])
def signup(request):
username = request.data.get('username')
password = request.data.get('password')
email = request.data.get('email')
phone = request.data.get('phone')
user = User.objects.create_user(username=username, password=password,
email=email)
if not user:
return Response({'message': 'Failed'}, status=HTTP_400_BAD_REQUEST)
return Response({'message': 'success'})
Do i need to implement any special signal to pass the input data like phone and address to profile model or extra lines i have to add.
Thanks in advance.

Save user specific data in Django

I am hacking Django, as I am new to it, to create a website to which user can login and can answer some questions. For logged in user I intend to store their username, question id and response to the question. However, after trying for multiple hours I have been completely unsuccessful. Below I have given snippets of Models.py and Views.py
Models.py - I am copying only UserProfile class and Userresponse class which are needed to create the User Profile and User Response table
# Model class for creating user
class UserProfile(models.Model):
user = models.OneToOneField(User)
def __str__(self):
return self.user.username
# Model class for getting user response
class UserResponse1(models.Model):
user = models.ForeignKey(UserProfile, default=0)
questoinId = models.ForeignKey(Question)
option = models.IntegerField(default=0)
```Views.py``
def response(request, question_id):
q = UserResponse1()
if request.user.is_authenticated():
q.user = request.user.username
q.questionId_id = question_id
q.option +=request.POST['choice']
q.save()
# Redisplay the question voting form.
return HttpResponseRedirect(reverse('polls:overallResults'))
However, on running above I get following error - Cannot assign "u'abc123'": "UserResponse1.user" must be a "UserProfile" instance.
abc123 is the login name of the user. I am not able to figure out the reason for this error. Any help on fixing this error so that I can write the data to UserResponse1 table, will be very helpful.
I am using Django 1.8 on Python 2.7
q.user is a foreign key to the UserProfile table, so you have to assign a user profile instance.
Since you have access to the user with request.user you can access the user profile using the one to one field.
user_profile = request.user.userprofile
q.user = user_profile

"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)

Django: CreateView with additional field?

I am trying to program a Django CreateView (CBV), which takes instead of the user id the user email and determines (or creates) the user based on the email.
My model does not contain anything special:
class Project(models.Model):
name = models.CharField(_('Title'), max_length=100,)
user = models.ForeignKey(User, verbose_name=_('user'),)
...
My forms.py adds the additional email field to the form:
class ProjectCreateForm(forms.ModelForm):
email = forms.EmailField(required=True, )
class Meta:
model = Project
fields = ('name', ...,)
In my views.py, I am trying to determine if the user exists or should be created. In both cases, the user id should be saved as part of the Project instance.
class ProjectCreateDetails(CreateView):
form_class = ProjectCreateForm
template_name = '...'
success_url = reverse_lazy('login')
model = Project
def form_valid(self, form):
try:
user = User.objects.get(email=form.email)
except User.DoesNotExist:
user = User.objects.create_user(form.email, form.email, ''.join([random.choice(string.digits + string.letters) for i in range(0, 10)]))
user.save()
form.instance.user = user
return super(ProjectCreateDetails, self).form_valid(form)
However I am facing an error that the 'Solution' object has no attribute 'email'.
Do I need to switch to a FormView instead of a CreateView?
You get the error 'Solution' object has no attribute 'email' because form.email is invalid. Validated data is never available as attributes of a form or model form. When forms (including model forms) are valid, the successfully validated data is available in the form.cleaned_data dictionary.
Note that you don't need to call user.save(). The create_user call has already added the user to the database. You don't have to generate a random password either -- if password is None, then create_user will set an unusable password.
Finally, make sure that you do not include the user field in the ProjectCreateForm. You probably do not, but your code says fields = ('name', ...,) so I can't tell for sure.
Put it together and you get the following (untested) code:
def form_valid(self, form):
try:
user = User.objects.get(email=form.cleaned_data['email'])
except User.DoesNotExist:
user = User.objects.create_user(form.cleaned_data['email'], form.cleaned_data['email'])
form.instance.user = user
return super(ProjectCreateDetails, self).form_valid(form)

Categories