How to change data inside table django? - django

I have been creating clone of Twitter. User can register, login, write tweets. Tweet modal is here:
class TweetModel(models.Model):
text = models.TextField(max_length=300, blank=False)
created_at = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True)
username = models.CharField(max_length=100, blank=True)
def __str__(self):
return f'{self.username}: {self.text[0:15]}'
Once user changes his/her username, I want to change username in the tweets they write also.
How can I handle this? Thank you.

You don't need to store the username in TweetModel. You can have access to the username like this:
tweet = TweetModel.objects.get(pk=1).owner.username
owner is a ForeignKey which means it stores the user id and .owner means to find the user with this id and .username means to return the username field for that user.
Now you're directly accessing the User table so any changes will be there.

Related

How to search for objects in the Django User model

I have a Profile model:
from django.contrib.auth.models import User
class Profile(models.Model):
first_name = models.CharField(max_length=100, blank=True)
last_name = models.CharField(max_length=100, blank=True)
user = models.OneToOneField(User, on_delete=models.CASCADE)
birthday = models.DateField(null=True, blank=True)
bio = models.TextField(blank=True, max_length=1000)
location = models.CharField(max_length=100, blank=True)
...
And a search contacts view:
class SearchContactsView(ListView):
model = Profile
template_name = 'users/contact_search.html'
context_object_name = 'qs'
def get_queryset(self):
q1 = self.request.GET.get('contact_name')
q2 = self.request.GET.get('contact_location')
if q1 or q2:
return Profile.objects.filter(Q(first_name__icontains=q1) |
Q(last_name__icontains=q1),
location__icontains=q2)
return Profile.objects.all()
It is working fine but I would like to be able to search for contacts via the user field as well. Does anyone know a way to do that?
EDIT my user's username's are created by them when they sign up to the site and are currently uneditable. They are displayed on the admin page via a dropdown since they are a OneToOneField. I think my issue is that django recognises them only as an IntegerField('pk') but I need to somehow cast them as a string value. Am I right in thinking that, and if so how can this be achieved?
You can add to your template to allow user to input user_username and save that username to q3:
q3 = self.request.GET.get('user_username')
After that you can adjust your If condition accordingly, then change your return to something like:
Profile.objects.filter(Q(first_name__icontains=q1) |
Q(last_name__icontains=q1),
location__icontains=q2,
user__username=q3)

How to create 'terms & conditions check box' in django?

I want to make a registration form like this, where user would type username,email,password,confirm password and check the terms and condition box to register his/herself. But i dont know how to create a model row for check box so that according to its input i would allow or disallow user to register.
models.py
class registeration(models.Model):
username = models.CharField(max_length=100)
email = models.EmailField()
password = models.CharField(max_length=100)
confirm_pasword = models.CharField(max_length=100)
def __str__(self):
return self.username
You can use BooleanField for this:
terms_confirmed = models.BooleanField()

Add custom user using django-allauth extra data

I would like to save data I get with allauth package after signing up using facebook.
I made a custom user :
class AppUser(models.Model):
birthdate = models.DateTimeField(null=True, blank=True)
address = adress_model.AddressField(null=True, blank=True)
image = models.ImageField(upload_to=get_image_path, blank=True, null=True)
gender = models.TextField(null=True, blank=True)
user = models.OneToOneField(User)
I would like to store all data in the database so I can easily access it from database.
P.S: If u can tell me how I can make a login page with button that will trigger it as well it would be great!
You can either use the save() method of the model to extract and save the data:
save(self, *wargs, **kwargs)
social_account = self.socialaccount_set.get(provider="facebook")
self.first_name = social_account.extra_data['first_name']
super(User, self).save(*wargs, **kwargs)
Or you can use the provided signal by allauth:
allauth.socialaccount.signals.social_account_added(request, sociallogin)
Check here for signal docs: http://django-allauth.readthedocs.io/en/latest/signals.html

Django query to filter username in correct format

There is model OraganisationUser :
class OrganisationUser(CommonInfo):
active = models.BooleanField(default=True)
user = models.OneToOneField(User, related_name='organisation_user')
managers = models.ManyToManyField('self', related_name='employees_managed', null=True, default=None, blank=True, symmetrical=False)
approvers = models.ManyToManyField('self', related_name='approvees', null=True, default=None, blank=True, symmetrical=False)
organisation = models.ForeignKey(Organisation, related_name='employees')
user_details = models.OneToOneField('OrganisationUserDetails', null=True, blank=True)
super_admin = models.ForeignKey('self', related_name='organisation_employees', null=True, blank=True)
objects = OrganisationUserManager()
gems = models.PositiveIntegerField(default=0, null=True, blank=True)
rank = models.PositiveIntegerField(default=0, null=True, blank=True)
I have written a query to filter user name in views.py :
username = OrganisationUser.objects.filter(user = id)
print username
Its printing : [<OrganisationUser: nirmal>]
I want to fetch nirmal from above result.
filter returns a list of objects. Use get to get a single object and navigate to the username:
username = OrganisationUser.objects.get(user=id).user.username
Better yet, look up the user directly
username = User.objects.get(pk=id).username
Is there a possibility of not finding the user with that id?
Where are you getting the id? Is this the logged in user? Then he is available in request.user, and his username in request.user.username.
The problem in your code is that 'username' has the organisationuser object. With that object (in your code username), you can access any atribute like active,user,managers,organisation,userdetails.... just adding a dot between object and atribute.
You can do it like this:
orguser = OrganisationUser.objects.filter(user = id)
print orguser #This print the object OrganisationUser
print orguser.user #This print the object User, wich the onetoonefield is pointing to
print orguser.user.username #This print the username, of the user pointed by the one to one field
Example managing django object. Get attribute value:
object = OrganisationUser.objects.filter(user = 1) #Get the object with id=1
print object.active #This will print the value for this attribute (active)

Django - Linking my models to profiles (UserProfile) model

I'm trying to create a small app for users to have contacts. I'm using django-profiles as a base for my profiles. Now everything works well until I try to submit the edit contact form and I receive this error.
Cannot assign "<Contact: Contact object>": "Contact.user" must be a "UserProfile" instance.
Being pretty new to Django, I'm not even sure if I'm taking the right approach here. My end goal is for the user to be able to add as many contacts as neccessary.
Any advice is appreciated.
My UserProfile model which extends User looks like:
class UserProfile(models.Model):
#User's Info
user = models.ForeignKey(User, unique=True)
first_name = models.CharField("first name", max_length=30)
last_name = models.CharField("last name", max_length=30)
home_address = models.CharField(max_length=50)
primary_phone = PhoneNumberField()
city = models.CharField(max_length=50)
state = USStateField()
zipcode = models.CharField(max_length=5)
birth_date = models.DateField()
gender = models.CharField(max_length=1, choices=GENDER_CHOICES, blank=True)
and my contact model looks like this:
class Contact(models.Model):
user = models.ForeignKey(UserProfile)
contact_description = models.CharField("Relation or Description of Contact", max_length=50, blank=True)
contact_first_name = models.CharField("contact first name", max_length=30)
contact_last_name = models.CharField("contact last name", max_length=30)
contact_primary_phone = PhoneNumberField("contact primary phone number")
contact_secondary_phone = PhoneNumberField("contact secondary phone number",blank=True)
and my view:
def editContact(request, username, object_id=False, template_name='contacts/edit.html'):
user = UserProfile.user
AddContactFormset = inlineformset_factory(UserProfile,Contact, extra=1)
if object_id:
contact=Contact.objects.get(pk=object_id)
else:
contact=Contact()
if request.method == 'POST':
f= ContactForm(request.POST, request.FILES, instance=contact)
fs = AddContactFormset(request.POST, instance=contact)
if fs.is_valid() and f.is_valid():
f.save()
fs.save()
return HttpResponse('success')
else:
f = ContactForm(instance=contact)
fs = AddContactFormset(instance=contact)
return render_to_response(template_name ,{'fs':fs,'f':f,'contact': contact}, context_instance=RequestContext(request))
Basically, django-profiles is for something else - it's just helping to create and manage user profiles across an application.
First of all - you should link Contact models directly to the django.contrib.auth.models.User via ForeignKey. This way you can access given User's contacts by a simple query ie. User.contact_set.all() - it will return to you a list of User's contacts. This will also get rid off your error.
Second - fields like first_name, last_name are already definied in django.contrib.auth.models.User, so there is no need to define them again in UserProfile. Read the source of User model here
Third - if your user can only have one Profile and you're not intend to use very old versions of django then you should be using OneToOneField instead of ForeignKey.
Fourth thing - you could probably omit usage of RequestContext() by using one of the generic views bundled with django - read about that here
Last thing - remember that main model for handling the Users is the User model itself. Any custom Profile is just an extension, so link everything which is related to the User to the User model itself.
Happy coding!
To elaborate on bx2's answer, your Contact model should look more like this:
class Contact(models.Model):
user = models.ForeignKey(User, related_name='contacts')
contact_description = models.CharField("Relation or Description of Contact", max_length=50, blank=True)
contact_first_name = models.CharField("contact first name", max_length=30)
contact_last_name = models.CharField("contact last name", max_length=30)
contact_primary_phone = PhoneNumberField("contact primary phone number")
contact_secondary_phone = PhoneNumberField("contact secondary phone number",blank=True)
Your view, frankly, does not make much sense. In general an inline formset is meant to represent records related to some parent record. In your case, it would be the user record, with the contacts being the "children" records. But having both a Contact form and an AddContactFormset doesn't make a lot of sense.
Also, I'd recommend against using variable names like f and fs in Django. Apart from variables like indexes, counters, etc. it doesn't serve any purpose to use short 1-2 character variable names. Go ahead and use longer variable names like form and formset, or even contact_form and contact_formset. It makes it much, much easier to debug the code in the future.