Create token with different model than user in django - django

I am trying to create an authentication token for my model called Person, but the Token table asks me for a user_id as a foreign key, is there any way I can create tokens with a different User model?
This is my Person model:
class Person(AbstractBaseUser):
first_name = models.CharField('Nombre', max_length = 100)
last_name = models.CharField('Apellido', max_length = 100)
username = models.CharField('Username', max_length = 50)
nickname = models.CharField('Nickname', max_length = 50, null = True)
gener = models.IntegerField('Genero')
phone = models.CharField('Teléfono', max_length = 13, null = True)
birtday = models.DateField('Cumpleaños', auto_now=False, auto_now_add=False, null = True)
address_id = models.IntegerField('Dirección', null = True)
address_birtday_id = models.IntegerField('Lugar de Nacimiento', null = True)
email = models.EmailField('Correo', max_length=254)
password = models.CharField('Password', max_length = 700)
photo = models.CharField('Foto', max_length=254, null = True)
about_me = models.CharField('Biografía', max_length = 1000, null = True)
active = models.IntegerField('Activo')
connected = models.IntegerField('Conectado')
person_type_id = models.IntegerField('Tipo', null = True)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, null=True, blank=True)
USERNAME_FIELD = 'username'
def __str__(self):
return '{0},{1}'.format(self.last_name, self.first_name)
This is my view:
class LoginPersonAPI(APIView):
def post(self, request):
serializer = LoginPersonSerializer(data = request.data)
if serializer.is_valid():
person = Person.objects.filter(username=serializer.validated_data['username'])
token = Token.objects.get_or_create(key = person[0].id)
if token:
return Response(token[0])
return Response(person[0].id, status = status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST)
This is my serializer:
class LoginPersonSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField()
def login(self, validate_data):
instance = Person
instance.username = validate_data.get("username")
instance.password = validate_data.get("password")
instance.find()
return instance
and this is the error
null value in column "user_id" violates not-null constraint
DETAIL: Failing row contains (3, 2020-06-27 19:39:53.283721+00, null).

Related

Django error - __str__ returned non-string (type User)

I have the below 2 models - User and PhoneProfile.
I can successfully create records for User. When i browse to PhoneProfile using admin console, i can see the foreign key present. On selection of an entry and completion of the rest of the fields, i get the error below.
class User(AbstractBaseUser):
phone_regex = RegexValidator(regex = r'^\+?1?\d{2,14}$', message = "Phone number must be in the format: '+xxxxxxxxxx'.")
phone = models.CharField(validators = [phone_regex], max_length = 15, unique = True)
first_name = models.CharField(max_length = 50, blank = False, null = False)
last_name = models.CharField(max_length = 50, blank = False, null = False)
email = models.CharField(max_length = 100, blank = True, null = True)
first_login = models.BooleanField(default = False)
active = models.BooleanField(default = True)
staff = models.BooleanField(default = True)
admin = models.BooleanField(default = False)
timestamp = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'phone'
REQUIRED_FIELDS = []
objects = UserManager()
class PhoneProfile(models.Model):
registered_phone = models.ForeignKey(User, on_delete=models.CASCADE, related_name='registered_phone')
notify_enable_low_bal = models.BooleanField()
notify_amount_low_bal = models.DecimalField(decimal_places=2, max_digits=10000, default='50', null=True)
Error message when i attempt to create an entry in PhoneProfile model
__str__ returned non-string (type User)
Request Method: POST
Request URL: http://localhost:8000/admin/smartrecharge/phoneprofile/add/
Django Version: 3.0.7
Exception Type: TypeError
Exception Value:
__str__ returned non-string (type User)
Exception Location: /Users/django-backend/venv/lib/python3.7/site-packages/django/contrib/admin/options.py in log_addition, line 807
Python Executable: /Users/django-backend/venv/bin/python
Python Version: 3.7.7
Python Path:
Any guide will be appreciated. Thanks
the value you are getting in the class string representation is non string so you have to change the def str(self) method and convert returning data into string and if there is no data than make one like given below
class User(AbstractBaseUser):
phone_regex = RegexValidator(regex = r'^\+?1?\d{2,14}$', message = "Phone number must be in the format: '+xxxxxxxxxx'.")
phone = models.CharField(validators = [phone_regex], max_length = 15, unique = True)
first_name = models.CharField(max_length = 50, blank = False, null = False)
last_name = models.CharField(max_length = 50, blank = False, null = False)
email = models.CharField(max_length = 100, blank = True, null = True)
first_login = models.BooleanField(default = False)
active = models.BooleanField(default = True)
staff = models.BooleanField(default = True)
admin = models.BooleanField(default = False)
timestamp = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'phone'
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
return str(self.phone_regex)
do the same changes in the other class you specify in the question

Insert or update on table violates foreign key constraint (error)

I am trying to save form data into a postgres table 'Student_Events' that is linked via foreign key to the 'Student_INFO table' but keep on receiving an integrity error:
'insert or update on table "entry_student_event" violates foreign key constraint "entry_student_event_nsn_id_2499e7fd_fk_entry_student_info_id"
DETAIL: Key (nsn_id)=(123556789) is not present in table "entry_student_info".'
There is one student in Student_INFO that has the nsn '123556789' so I am unsure to why it "is not present" in that table. Any help would be greatly appreciated as I am quite new to Django and PostgresSQL,
thanks
Views.py:
def Grouplist(request):
student_list = Student_INFO.objects.order_by('name')
for student in student_list:
if request.method == 'POST':
form = EntryForm(request.POST)
context = {
'student_list':student_list,
'form': form
}
if form.is_valid():
event_save = form.save(commit=False)
event_save.nsn_id = student.nsn
event_save.save()
return redirect('grouplist')
else:
form = EntryForm()
context = {
'student_list':student_list,
'form': form
}
return render(request, 'grouplist.html', context)
Models.py:
class Student_INFO(models.Model):
nsn = models.IntegerField(blank = False)
birthdate = models.DateField("BirthDate", blank = False)
name = models.CharField(max_length=30, blank = False)
age_catagory = models.CharField(max_length=8, blank = True, default = '')
grouproom = models.CharField(max_length=3, blank = False)
year_lvl = models.IntegerField(blank = False)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
class Student_Event(models.Model):
nsn = models.ForeignKey(Student_INFO, on_delete=models.CASCADE)
event1 = models.CharField(max_length=15, blank=False, default = '')
event2 = models.CharField(max_length=15, blank=False, default = '')
event3 = models.CharField(max_length=15, blank=False, default = '')
event4 = models.CharField(max_length=15, blank=False, default = '')
event5 = models.CharField(max_length=15, blank=False, default = '')
event6 = models.CharField(max_length=15, blank=False, default = '')
def __str__(self):
return self.nsn
Forms.py
class EntryForm(forms.ModelForm):
class Meta:
model= Student_Event
fields= ["event1", "event2", "event3", "event4", "event5", "event6"]
widgets = {
'event1':forms.Select(choices=EVENT_CHOICES),
'event2':forms.Select(choices=EVENT_CHOICES),
'event3':forms.Select(choices=EVENT_CHOICES),
'event4':forms.Select(choices=EVENT_CHOICES),
'event5':forms.Select(choices=EVENT_CHOICES),
'event6':forms.Select(choices=OPEN_CHOICES),
}
Returns the error:
insert or update on table "entry_student_event" violates foreign key constraint "entry_student_event_nsn_id_2499e7fd_fk_entry_student_info_id"
DETAIL: Key (nsn_id)=(123556789) is not present in table "entry_student_info".
Thank you #BearBrown for solving it! student.nsn should be student.pk.

Model's fields being cleared after ModelForm.save() called

I'm having an issue where I instantiate a ModelForm-based form with a pre-existing instance of the model in the GET portion of my view function. This model already has several fields filled in; the ModelForm is used to collect other fields in the model. The pre-existing fields are excluded in the ModelForm's definition.
The problem is, during POST processing, after successful validation of the ModelForm, I'm calling ModelForm.save(commit=False)...and the model returned (which should be the same one I passed in as 'instance' in the GET handling, remember) has somehow lost all the fields that were previously set. The fields actually set by the form are fine; but it's no longer the original instance of my model.
This is not the behavior I expected; and in fact I've used this partial-model-in-modelform previously, and it works other places. What am I missing here??
Hopefully some code'll make all this clear...
So here's the Model:
class Order(models.Model):
STATUS = (
('Created', -1),
('Pending', 0),
('Charged', 1),
('Credited', 2),
)
SHIPPING_STATUS = (
('Cancelled', 0),
('Ready for pickup', 1),
('Shipped', 2),
('OTC', 3),
)
orderID = models.IntegerField(max_length=15, null=True, blank=True)
store = models.ForeignKey(Store)
paymentInstrument = models.ForeignKey(PaymentInstrument, null=True, blank=True)
shippingMethod = models.ForeignKey(ShippingMethod, null=True, blank=True)
last_modified = models.DateTimeField(null=True, blank=True)
date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
total = models.FloatField(default=0.0, blank=True)
shippingCharge = models.FloatField(default=0.0, blank=True)
tax = models.FloatField(default=0.0, blank=True)
status = models.CharField(max_length=50, choices=STATUS, default = 'Created')
shippingStatus = models.CharField(max_length=50, choices=SHIPPING_STATUS, default = '1')
errstr = models.CharField(max_length=100, null=True, blank=True)
# billing info
billingFirstname = models.CharField(max_length = 50, blank = True)
billingLastname = models.CharField(max_length = 50, blank = True)
billingStreet_line1 = models.CharField(max_length = 100, blank = True)
billingStreet_line2 = models.CharField(max_length = 100, blank = True)
billingZipcode = models.CharField(max_length = 5, blank = True)
billingCity = models.CharField(max_length = 100, blank = True)
billingState = models.CharField(max_length = 100, blank = True)
billingCountry = models.CharField(max_length = 100, blank = True)
email = models.EmailField(max_length=100, blank = True)
phone = models.CharField(max_length=20, default='', null=True, blank=True)
shipToBillingAddress = models.BooleanField(default=False)
# shipping info
shippingFirstname = models.CharField(max_length = 50, blank = True)
shippingLastname = models.CharField(max_length = 50, blank = True)
shippingStreet_line1 = models.CharField(max_length = 100, blank = True)
shippingStreet_line2 = models.CharField(max_length = 100, blank = True)
shippingZipcode = models.CharField(max_length = 5, blank = True)
shippingCity = models.CharField(max_length = 100, blank = True)
shippingState = models.CharField(max_length = 100, blank = True)
shippingCountry = models.CharField(max_length = 100, blank = True)
Here's the ModelForm definition:
class OrderForm(ModelForm):
class Meta:
model = Order
exclude = ('orderID',
'store',
'shippingMethod',
'shippingStatus',
'paymentInstrument',
'last_modified',
'date',
'total',
'payportCharge',
'errstr',
'status', )
widgets = {
'billingCountry': Select(choices = COUNTRIES, attrs = {'size': "1"}),
'shippingCountry': Select(choices = COUNTRIES, attrs = {'size': "1"}),
'billingState': Select(choices = STATES, attrs = {'size': "1"}),
'shippingState': Select(choices = STATES, attrs = {'size': "1"}),
}
And here is the view function:
def checkout(request):
theDict = {}
store = request.session['currentStore']
cart = request.session.get('cart', False)
order = request.session['currentOrder'] # some fields already set
if not cart: # ...then we don't belong on this page.
return HttpResponseRedirect('/%s' % store.urlPrefix)
if request.method == 'GET':
form = OrderForm(instance=order, prefix='orderForm')
else: # request.method == 'POST':
logging.info("Processing POST data...")
form = OrderForm(request.POST, prefix='orderForm')
if form.is_valid():
### AT THIS POINT, ORDER FIELDS ARE STILL GOOD (I.E. FILLED IN)
order = form.save(commit=False)
### AFTER THE SAVE, WE'VE LOST PRE-EXISTING FIELDS; ONLY ONES SET ARE
### THOSE FILLED IN BY THE FORM.
chargeDict = store.calculateCharge(order, cart)
request.session['currentOrder'] = order
return HttpResponseRedirect('/%s/payment' % store.urlPrefix)
else:
logging.info("Form is NOT valid; errors:")
logging.info(form._errors)
messages.error(request, form._errors)
theDict['form'] = form
theDict['productMenu'] = buildCategoryList(store)
t = loader.get_template('checkout.html')
c = RequestContext(request, theDict)
return HttpResponse(t.render(c))
Any/all help appreciated...
When you instantiate the form during the POST, the instance of the model you're editing is None, because you're not passing it in, and you're not persisting the form instance from the GET. Django won't do anything on its own to persist data between requests for you.
Try:
...
form = OrderForm(request.POST or None, instance=order, prefix='orderForm')
if request.method == 'POST':
logging.info("Processing POST data...")
if form.is_valid():
...
Now the instance will be populated for GET and POST, but the data from request.POST is optional for the form if it's None. It also saves you from having to instantiate the form in two places depending on request.method

Get all object from Django ForeignKey Field

I have two models, an Event and a suggestedName. suggestedName has a ForeignKey relationship with Event as well as a IntegerField called 'votes'. I want to get the top 5 suggestedNames associated with an Event.
My models:
class Event(models.Model):
def __unicode__(self):
return unicode(self.id)
id = models.BigIntegerField(blank = 'TRUE', primary_key='TRUE')
version = models.IntegerField(default = 0)
views = models.IntegerField(default = 0)
created = models.DateTimeField(editable = False)
modified = models.DateTimeField()
trained = models.BooleanField(default = False)
type = models.SmallIntegerField(default = 0)
class suggestedName(models.Model):
def __unicode__(self):
return self.name
name = models.CharField(max_length=200, blank = 'TRUE', null = 'TRUE')
votes = models.IntegerField(default = 0)
event = models.ForeignKey(Event)
What I have in my view is this:
e = Event.objects.get(pk=event_id)
suggestedN = e.suggestedName_set.order_by('votes')[:5].reverse()
But I'm not getting any results.
Try:
e.suggestedname_set.order_by('-votes')[:5]
Or specify a related name
class suggestedName(models.Model):
def __unicode__(self):
return self.name
name = models.CharField(max_length=200, blank = True, null = True)
votes = models.IntegerField(default = 0)
event = models.ForeignKey(Event, related_name='suggestions')
and then,
e.suggestions.order_by('-votes')[:5]

How to set a Django Boolean value to True when by default, it is false?

I have a django view where users can sign up. For any user who signs up from this point forward, I would like to set the boolean value to True.
class Person(models.Model):
user = models.OneToOneField(User, primary_key=True)
facebook_id = models.CharField(max_length=225, unique=True, null=True, blank=True)
twitter_id = models.CharField(max_length=225, unique=True, null=True, blank=True)
suggested_person = models.BooleanField(default=False)
userPic = models.CharField(max_length=128, blank=True)
phoneNum = models.CharField(max_length=128, blank=True)
Sign-Up Django view:
#csrf_exempt
def signup(request):
if request.method == 'POST':
# Parse the JSON
data = json.loads(request.raw_post_data)
# Check if the user already exists
if User.objects.filter(username = data['username']).exists():
return HttpResponse("Username already exists")
# If not then create new user with the supplied info
else:
newUser = User()
newUser.username = data['username']
newUser.email = data['email']
newUser.set_password(data['password'])
newUser.first_name = data['firstName']
newUser.last_name = data['lastName']
newUser.save()
newPerson = Person(user = newUser, phoneNum = data['phoneNum'], userPic = data['userPic'], userCover = data['userCover'])
if 'token' in data:
if Person.objects.filter(token=data['token']).exists():
oldToken = Person.objects.get(token=data['token'])
oldToken.token = None
oldToken.save()
newPerson.token = data['token']
newPerson.save()
else:
newPerson.token = data['token']
newPerson.save()
#perhaps like this? newPerson.suggested_person =True
newPerson.save()
newUser.relationships.add(newUser)
return HttpResponse(str(newUser.id))
# If not POST
else:
return HttpResponse("Signup here People")
How can I go about making any user who signs up from this point forward a 'suggested_person'?
If you can't or don't want to change the default definition on your model, you can either pass in your desired value when creating your Person instance:
newPerson = Person(user = newUser, phoneNum = data['phoneNum'], userPic = data['userPic'], userCover = data['userCover'], suggested_person=True)
Or you can set the attribute prior to saving:
newPerson.suggested_person = True