Unique token using uuid is generating same codes - django

im using uuid token to activate users account , so every client created have their own code in the Client model , but when i create new client it generate always the same Token as others , i have used the uuid 4 , is their anyother ways to generate unique client code to activate their account or some other method then uuid , or just im missing a point on how to generate uuid on models ,
their is my model and client creation codes :
Model.py :
def generateUUID():
return str(uuid4())
class client(models.Model):
name = models.CharField(max_length=45, unique=True)
email = models.EmailField(max_length=85)
date_of_birth = models.DateField(null=True, blank=True)
height = models.IntegerField(null=True, blank=True)
weight = models.IntegerField(null=True , blank=True)
created_at = models.DateTimeField(auto_now_add=True)
picture = models.URLField(null=True ,blank=True)
affiliation = models.ForeignKey(User, on_delete=models.CASCADE, related_name="client_coach")
reference = models.OneToOneField(User, on_delete=models.CASCADE, null=True , blank=True)
is_active = models.BooleanField(default=False)
token = models.CharField( max_length=85, default=generateUUID())
def __str__(self):
return self.name
def getname(self):
return self.coach.name
view.py:
if request.method == 'POST' and request.POST['action'] == 'client':
form = ClientForm(request.POST)
print(form)
name = request.POST.get('name')
email = request.POST.get('email')
#client_code = code.objects.create()
new_client = client.objects.create(name = name, email = email, affiliation = request.user)
new_client.save()
return JsonResponse({'client': model_to_dict(new_client)}, status=200)

You need to create a custom save method and assign this there.
def save(self, *args, **kwargs):
self.token = generateUUID()
super(client, self).save(*args, **kwargs)

Related

Django User matching query does not exist on foreign-key relation

I am trying to create a system in Django by which users will login using a phone number. Used AbstractBaseUser to use the number as user id. Now I am trying to create a foreign key relation of every transaction with the number. While I try to push a transaction, it says "User matching query does not exist". I am getting where I made mistake.
User model:
class User(AbstractBaseUser, PermissionsMixin):
phone_number = models.CharField("Phone number", max_length=100, unique=True, error_messages={
'unique': ("number_existsssss"),
})
name = models.TextField("Name")
time_stamp = models.DateTimeField("Time-Date", auto_now=True)
request_type = models.CharField(max_length=100, default="check"
is_staff = models.BooleanField(verbose_name=('staff status'), default=False)
is_active = models.BooleanField(verbose_name=('active'), default=True)
Transaction Model:
class TransactionModel(models.Model):
trxID = models.CharField(max_length=15, null=True, unique=True)
User = models.ForeignKey(to=User, to_field="phone_number", related_name='transaction', on_delete=models.DO_NOTHING, default=1)
time = models.DateTimeField(auto_now=True, null=True)
amount = models.CharField(max_length=5, null=True)
pay_method = models.CharField(max_length=10, null=True)
amountReceivedFrom = models.CharField(max_length=26, null=True)
transactionStatus = models.CharField(max_length=15, null=True, default='False')
view for add-cash/b-kash request:
class BkashCashinView(APIView):
#transaction.atomic
def post(self, request, *args, **kwargs):
HEADERS = {
"Access-Control-Allow-Origin": "*"
}
if request.method == 'POST':
serializer = BkashCashinSerializer(data = request.data)
# serializer.is_valid()
req = request.data
trx_id = req.get('trxID')
print(trx_id)
phone_number = req.get('phone_number')
recharge_amount = float(req.get('amount'))
number_exists = User.objects.filter(phone_number=phone_number).exists()
user = User.objects.get(phone_number=phone_number)
print(user)
current_user_data = User.objects.select_for_update().get(phone_number=phone_number)
# current_user_data = User.objects.get(phone_number=phone_number)
with transaction.atomic():
current_user_data.current_balance += recharge_amount
current_user_data.save()
print("phone numbe", req.get("amount"))
serializer.is_valid(raise_exception=True)
current_balance = current_user_data.current_balance
context = {
"current_balance": current_balance,
"status": "success"
}
serializer.save()
# print(trx_id)
return Response(context, headers = HEADERS)
I think I made some mistakes with the foreign key relation. The error shows:
raise self.model.DoesNotExist(
user_signup.models.User.DoesNotExist: User matching query does not exist.
[04/Sep/2021 18:44:22] "POST /add-cash/b-kash HTTP/1.1" 500 20728

form not saving into user model Django

I'm currently processing a payment thing for an online subscription service and in order to get the users info to send this stuff, I have a payment form.
But, for some reason the payment form is not saving to the users account. Everything else actually processes and the only error I can trigger is a 'NOT NULL constraint failed: memberships_usermembership.user_id'
Here's what I have in my view -
#login_required()
def payments(request):
user_membership = get_user_membership(request)
selected_membership = get_selected_membership(request)
form = SubscriptionForm()
if request.method == "POST":
form_data = {
'full_name': request.POST['full_name'],
'email': request.POST['email'],
'phone_number': request.POST['phone_number'],
'country': request.POST['country'],
'postcode': request.POST['postcode'],
'town_or_city': request.POST['town_or_city'],
'street_address1': request.POST['street_address1'],
'street_address2': request.POST['street_address2'],
'county': request.POST['county'],
}
token = request.POST['stripeToken']
form = SubscriptionForm(form_data)
if form.is_valid():
customer = stripe.Customer.retrieve(
user_membership.stripe_customer_id)
customer.source = token
customer.save()
subscription = stripe.Subscription.create(
customer=user_membership.stripe_customer_id,
items=[
{"plan": selected_membership.stripe_plan_id},
]
)
user_membership = get_user_membership(request)
selected_membership = get_selected_membership(request)
user_membership.membership = selected_membership
user_membership.save()
form.save(commit=True)
subscription_id = subscription.id
sub, created = Subscription.objects.get_or_create(
user_membership=user_membership)
sub.stripe_subscription_id = subscription_id
sub.active = True
sub.save()
try:
del request.session['selected_membership_type']
except BaseException:
pass
return render(request, 'memberships/update-success.html')
else:
return redirect(reverse('membership_list'))
context = {
'selected_membership': selected_membership,
'form': form,
}
return render(request, 'memberships/payment.html', context)
When the form.save() is the line above the return(render) line, it will process everything as normal, and the form information just wont save into the DB.
It flashes the NOT NULL error when the form.save() line is where it in in the code above.
Any ideas how to get this working?
Thanks!
EDIT: Here's a link to the entire error in Django - http://dpaste.com/140VD8M
& a screenshot of it too!
Here's my models -
class Membership(models.Model):
membership_type = models.CharField(
choices=MEMBERSHIP_CHOICES,
default='Free',
max_length=30)
price = models.IntegerField(default=15)
description = models.TextField(default="DESCRIPTION")
image_url = models.URLField(max_length=1024, null=True, blank=True)
image = models.ImageField(null=True, blank=True)
stripe_plan_id = models.CharField(max_length=40)
def __str__(self):
return self.membership_type
class UserMembership(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
full_name = models.CharField(max_length=50, null=True, blank=True)
email = models.EmailField(max_length=254, null=True, blank=True)
phone_number = models.CharField(max_length=20, null=True, blank=True)
country = CountryField(blank_label='Country', default="Ireland")
postcode = models.CharField(max_length=20, null=True, blank=True)
town_or_city = models.CharField(max_length=40, null=True, blank=True)
street_address1 = models.CharField(max_length=80, null=True, blank=True)
street_address2 = models.CharField(max_length=80, null=True, blank=True)
county = models.CharField(max_length=80, null=True, blank=True)
stripe_customer_id = models.CharField(max_length=40)
membership = models.ForeignKey(
Membership, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.user.username
def post_save_usermembership_create(
sender, instance, created, *args, **kwargs):
user_membership, created = UserMembership.objects.get_or_create(
user=instance)
if user_membership.stripe_customer_id is None or user_membership.stripe_customer_id == '':
new_customer_id = stripe.Customer.create(email=instance.email)
free_membership = Membership.objects.get(membership_type='Free')
user_membership.stripe_customer_id = new_customer_id['id']
user_membership.membership = free_membership
user_membership.save()
post_save.connect(post_save_usermembership_create,
sender=settings.AUTH_USER_MODEL)
class Subscription(models.Model):
user_membership = models.ForeignKey(
UserMembership, on_delete=models.CASCADE)
stripe_subscription_id = models.CharField(max_length=40)
active = models.BooleanField(default=False)
def __str__(self):
return self.user_membership.user.username
& here's my user membership def -
#login_required()
def get_user_membership(request):
user_membership_qs = UserMembership.objects.filter(user=request.user)
if user_membership_qs.exists():
return user_membership_qs.first()
return None
Instead of collecting all the form fields individually, you should be able to just pass the request.POST to the form like so:
form_data = request.POST
token = request.POST['stripeToken']
form = SubscriptionForm(form_data)
Other than that, without seeing the exact error message, there isn't much more to tell. If you update your question I will update my answer.
EDIT:
Without seeing your model and what get_user_membership() returns, it looks like you are missing a User object in a UserMembership class (but I can't tell without seeing more):
user_membership.user = request.user
Or something like that.

Saving data once (to be able to load to images to server) then updating the same instance after some changes

I'm saving the data from the post request a first time because I need the images to be uploaded to the server like the "upload_image" function suggests.
At the same time I have a couple of fields that are null and need to have some values via some external functions.
And then I need to save the whole object in the database.
The problem that I'm facing is that it saves the data twice in the database.
And the first saved object has all attributes null except for passengerPhoto, passengerPassport and agent. ( No errors shown btw)
Any ideas, please?
Thanks a lot!
#VIEW
class IdentityCheckView(CreateAPIView, generics.ListAPIView):
serializer_class = IdentityCheckSerializer
permission_classes = [permissions.AllowAny]
def get_queryset(self):
request = self.request
qs = IdentityCheck.objects.all()
query = self.request.GET.get('q')
if query is not None:
qs = qs.filter(name__icontains=query)
return qs
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if(serializer.is_valid()):
res = self.create(request, *args, **kwargs)
image = FaceRecognition.imageMatch(res.data['passengerPhoto'], res.data['passengerPassport'])
wanted = WantedPro.criminalMatch(res.data['passengerPhoto'])
passport_json = OCR.passportMatch(res.data['passengerPassport'])
image_json = json.loads(image)
firstName = passport_json['names']
lastName = passport_json['surname']
nationality = passport_json['country']
birthDate = passport_json['date_of_birth']
gender = passport_json['sex']
ableToBoard = bool(wanted) & bool(image_json['match']) & bool(passport_json['valid_expiration_date'])
serializer.update(
id=res.data['id'],
firstName=firstName,
lastName=lastName,
nationality=nationality,
birthDate=birthDate,
gender=gender,
ableToBoard=ableToBoard)
return Response({"image": image_json, "passport": passport_json, "wanted": wanted}, status=200)
def perform_create(self, serializer):
res = serializer.save(agent=self.request.user)
#SERIALIZER
class IdentityCheckSerializer(serializers.ModelSerializer):
class Meta:
model = IdentityCheck
fields = '__all__'
read_only_fields = ['agent', 'id']
#MODEL
def upload_image(instance, filename):
return "media/check/{agent}/{date}/{filename}".format(agent=instance.agent,date=datetime.datetime.today().strftime('%d-%m-%Y'), filename=filename)
class IdentityCheckQuerySet(models.QuerySet):
pass
class IdentityCheckManager(models.Manager):
def get_queryset(self):
return IdentityCheckQuerySet(self.model,using=self._db)
class IdentityCheck(models.Model):
agent = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
passengerPhoto = models.ImageField(upload_to=upload_image, null=False, blank=False)
passengerPassport = models.ImageField(upload_to=upload_image, null=False, blank=False)
lastName = models.CharField(max_length=255, null=True, blank=True)
firstName = models.CharField(max_length=255, null=True, blank=True)
birthDate = models.DateField(null=True, blank=True)
nationality = models.CharField(max_length=255, null=True, blank=True)
gender = models.CharField(max_length=1, null=True, blank=True)
ableToBoard = models.BooleanField(null=False, blank=False, default=False)
timestamp = models.DateTimeField(auto_now_add=True)
objects = IdentityCheckManager()

request.user.attribute returning unwanted value

Why does the following print(owner) return a different value that what's in my model? Is it possible to get the formattedusername defined below? I've simplified my def profile(request) and took out my other arguments till I can figure out the solution to getting formattedusername.
def profile(request):
owner = User.objects.get (formattedusername=request.user.formattedusername)
args = {'user':request.user.formattedusername}
print (owner)
return render(request, 'accounts/profile.html', args)
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
#3-alphas4numeric
[06/Nov/2017 16:18:11] "GET /account/profile/ HTTP/1.1" 200 1416
formattedusername in my model is stored in the database as HCA\3-alphas4numeric, it's also defined by the following, it's also the key field in all my other models and there isn't a way around using an integer for the key since it's a pre-existing database:
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
username = models.CharField(max_length=7, unique=True)
formattedusername = models.CharField(max_length=11, unique=True, primary_key = True)
first_name = models.CharField(max_length=40)
last_name = models.CharField(max_length=140)
date_joined = models.DateTimeField(default=timezone.now)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
facility = models.CharField(max_length=140)
jobdescription = models.CharField(max_length=140)
positiondescription = models.CharField(max_length=140)
coid = models.CharField(max_length=5)
streetaddress = models.CharField(max_length=140)
USERNAME_FIELD = 'username'
class Meta:
app_label = 'accounts'
db_table = "user"
def save(self, *args, **kwargs):
self.formattedusername = '{domain}\{username}'.format(
domain='HCA', username=self.username)
super(User, self).save(*args, **kwargs);
When you do print(owner), you will print out the value of USERNAME_FIELD. That's how AbstractBaseUser.__str__ is implemented.
def get_username(self):
"Return the identifying username for this User"
return getattr(self, self.USERNAME_FIELD)
def __str__(self):
return self.get_username()

using UserProfile to restrict access in view

I have an app that displays client assets on html posting pages. Each client authorized to use the system is assigned a profile:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
fullname = models.CharField(max_length=64, unique=False)
company = models.CharField(max_length=50, choices=CLIENT_CHOICES)
position = models.CharField(max_length=64, unique=False, blank=True, null=True)
...
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
def __unicode__(self):
return u'%s' % self.fullname
class Meta:
ordering = ['fullname']
class Admin:
pass
and there's a model for the post pages:
class PostPage(models.Model):
client = models.CharField(max_length=50, choices=CLIENT_CHOICES)
job_number = models.CharField(max_length=30, unique=True, blank=False, null=False)
job_name = models.CharField(max_length=64, unique=False, blank=False, null=False)
page_type = models.CharField(max_length=50, default='POST')
create_date = models.DateField(("Date"), default=datetime.date.today)
contact = models.ForeignKey(UserProfile)
contact2 = models.ForeignKey(UserProfile, related_name='+', blank=True, null=True)
contact3 = models.ForeignKey(UserProfile, related_name='+', blank=True, null=True)
contact4 = models.ForeignKey(UserProfile, related_name='+', blank=True, null=True)
def __unicode__ (self):
return u'%s %s %s' % (self.client, self.job_number, self.job_name)
class Admin:
pass
and finally, a very simple view function to display the pages:
def display_postings(request, job_number):
records = PostPage.objects.filter(job_number=job_number)
tpl = 'post_page.html'
return render_to_response(tpl, { 'records': records })
The problem is, if you work for and access the system from "ACME" company, there's no logic in the view that would prevent you from viewing records for "BETAMAX" company in addition to your own. How can I modify my view so that if say, user.profile.company = "ACME" , but the request returns a record where PostPage.client = "BETAMAX", access to the record is denied? Additionally, can I have one company group, say user.profile.company = "MY_COMPANY" that has access to all records?
Write a decorator that checks the company of the request.user for the view. The code would look something like this:
def belongs_to_company(func):
def decorator(request, *args, **kwargs):
has_permissions = False
# get current company
...
# get user's list of company
...
# if company not in user's list of company
if not has_permissions:
url = reverse('no_perms')
return redirect(url)
return func(request, *args, **kwargs)
return decorator
A better long term solution is to check out Role Based Access Control libraries like django-guardian