so i have a self referential table, each time a user is registered he receive an automatic rank from the user who created him like a tree structure. i'm trying to retrieve a list of users by rank till the deepest child.
how can i achieve this
here is a sample of my code when i register a new operator and giving him his rank.
user_id = get_jwt_identity()
if not (logged_user := User.query.filter_by(id=user_id).first()):
faliure(log_initiation)
return err_resp("Email is already being used.", "email_taken", 403)
if not (user_rank := Types.query.filter(Types.parent_id == logged_user.type_id).first()):
user_rank = Types(
parent_id=logged_user.type_id
)
db.session.add(user_rank)
db.session.commit()
user_rank.name = 'Rank_' + str(user_rank.id)
db.session.commit()
new_user = User(
email=email,
username=username,
name=data_name,
password=password,
phone_number=phone_number,
type=user_rank,
web_login=web_login,
joined_date=datetime.utcnow(),
)
Related
def cart(request):
if request.user.is_authenticated:
customer = request.user.customer
order, created = Order.objects.get_or_create(customer=customer, complete= False)
items = order.orderitem_set.all()
else:
items = []
context = {'items':items}
return render(request,'store/cart.html', context)
That is my add to cart code that still display that there is no related object.
User has no customer means when you are calling customer = request.user.customer, the request user object has no related customer in your database.
/*tests.py*/
def create_user(username, password):
user = get_user_model().objects.create_user(username=username, password=password)
return user
#helper function to populat database
def create_category(name, super, user):
category = Category.objects.get_or_create(name=name)[0]
category.super = super
category.user = user
category.save()
return category
# The following test is for the save and deleting of
# a page from the favorites list
class TestFavoritesFeature(TestCase):
def setUp(self):
self.user = create_user("testUser", "testPassword")
self.cat = create_category('python', self.super, self.user)
Both the object.create and object.get_or_create give an error for NOT NULL field. Above is the code , 2 models and both throw an error on only the id field that we do not even populate. It is the function's job to assign a unique id to it. The above is code from tests.py file. I am trying to populate DB for unit testing . In the actual code, these objects.get_or_create or objects.create do not give errors but are rather successful
In the .get_or_create(…) [Django-doc] you need to provide values for the super_cat, user and name, but you only did this for the name.
We can further simplify the method by using .update_or_create(…) [Django-doc] and use the defaults=… parameter to specify what to update or initialize in case the object is not/is created:
def create_category(name, super, user):
category, __ = Category.objects.update_or_create(
name=name,
defaults={'super_cat': super, 'user': user}
)
return category
I have on my website an inputfield only with an email, where customers can sign up for newsletters.
At the moment I am handling by a function if this customer (email) exists already, if not then the object is created, if not, then the object is catched.
There must be a simplier way to do that in Django? Any ideas? Thanks a lot
This is the simplified function:
def get_customer(email):
# all only lowercase in order to avoid multiple entries
email = email.lower()
if Customer.objects.filter(email=email).exists():
# get customer object
customer = Customer.objects.get(email=email)
else:
# save form input to database
customer = Customer.create(email)
customer.save()
return customer
This is the real function, where I also update optional parameters like name (which is an input in an other form):
def get_customer(name, email):
# all only lowercase in order to avoid multiple entries
email = email.lower()
if Customer.objects.filter(email=email).exists():
# get customer object
customer = Customer.objects.get(email=email)
# if no name available in customer object but name given here, then update customer object
if len(customer.name) == 0 and len(name) > 0:
Customer.objects.filter(id=customer.id).update(name=name)
else:
# save form input to database
customer = Customer.create(name, email)
customer.save()
return customer
P.S.: I know email = email.lower() is not 100% correct since #Gmail.com is not the same then #gmail.com ...
As far as I can see, get_or_create helps also in the second case:
def get_customer(name, email):
def customer_updated_name():
return len(customer.name) == 0 and len(name) > 0
email = email.lower()
customer, created = Customer.objects.get_or_create(email=email)
if created or customer_updated_name:
customer.name = name
customer.save()
return customer
I'm building a learning website that stores various data about the user's progress. Currently, I'm using sessions to do this. I want the following behaviour:
Unregistered users can return to the site at a later date and the site will remember their progress.
When a user creates an account, they will not lose any data about progress already collected.
When a registered user logs out, their progress should be hidden.
When a registered user logs back in, their progress should be restored.
Sessions work great for behaviors 1-3, but on step 4 the progress fails to be restored. If I understand how Django handles sessions correctly, all of the session data is destroyed when the user logs out. What would be the best way to save this data and restore it again when the user logs back in?
It seems like there's no best one way to do this, but the solution I came up with works well so I thought I would share it.
I created a separate table for storing key/value pairs permanently for registered users. Ideally, you might want to store the data as serialized JSON similar to how the django_sesssion table works, but simple character fields will also work:
class account_data(models.Model):
username = models.CharField(max_length=30)
key = models.CharField(max_length=30)
value = models.CharField(max_length=30, null=True, blank=True)
class Meta:
unique_together = ("username", "key")
Each time I want to save or retrieve a key value pair, I check if the user is logged in. If they aren't, I save the data to the session. If they are, I save the data to the account_data table. I built some functions to handle this:
from account_manager.models import account_data
def getSessionOrAccountData(request, key):
if request.user.is_authenticated():
username = request.user.username
try:
record = account_data.objects.get(username=username, key=key)
return record.value
except:
return None
else:
if key in request.session.keys():
return request.session[key]
else:
return None
def setSessionOrAccountData(request, key, value):
if request.user.is_authenticated():
username = request.user.username
try:
record = account_data.objects.get(username=username, key=key)
record.value = value
record.save()
except account_data.DoesNotExist:
record = account_data(username=username, key=key, value=str(value))
record.save()
else:
request.session[key] = value
def deleteSessionOrAccountData(request, key):
if request.user.is_authenticated():
username = request.user.username
account_data.objects.filter(username=username).filter(key=key).delete()
else:
del request.session[key]
Finally, when a user creates a new account, I want to copy any session data they might have over to the account_data table. The following code is run right after the new user account is created:
# save all existing session data to new user account
for key in request.session.keys():
record = account_data(username=request.POST['username'],
key=key,
value=str(request.session[key]))
record.save()
For this purpose, you can use the Django session, when the user is a guest user, you can save the data using the session, and when the user login, copy the data and delete the guest user.
def Add_To_Cart(request, pk):
if request.user.is_authenticated:
user = request.user
try:
""" Customer Model """
""" you can create user or guest user in Customer Model """
authenticate_user, created = Customer.objects.get_or_create(user=user)
customer = authenticate_user
""" here you can get guest user account """
guest_user = Customer.objects.get(user=None)
""" i have two models for my E-commerce website(OrderPost|Order) """
""" here you can copy and create OrderPost objects from guest_user """
guest_orderitems = OrderPost.objects.get(user=guest_user, ordered=False)
order_item, created = OrderPost.objects.get_or_create(
user=customer,
item= guest_orderitems.item,
qunatity= guest_orderitems.qunatity,
ordered=False
)
guest_user.delete()
except:
authenticate_user, created = Customer.objects.get_or_create(user=user)
customer = authenticate_user
else:
""" When a guest user visits your website,
the guest user will be created without username and only with session_key """
try:
session_key = request.COOKIES['sessionid']
except:
return '0'
customer, created = Customer.objects.get_or_create(session_key=session_key)
I have models.py
class Visit(Model):
reference_visit = models.ForeignKey('self',
help_text="Visit needs a refrence to Prior Visits",
null=True, blank=True)
show_prior_responses = models.BooleanField(default=False,
help_text="Show PriorResponses")
# has many field but i am making it short.
def __unicode__(self):
result = """Visit id:%s pt:%s""" % (self.id, self.patient.id)
return result
forms.py
class VisitSetupForm(Form):
list_visit_ids = ModelChoiceField(
queryset=Visit.objects.none(),
empty_label='Select Revisit ID',required=False)
show_prior_visit = ModelChoiceField(
queryset=User.objects.all(),
empty_label="Select User for Revisit",required = False)
has many but question is on list_visit_ids.
views.py
def setup(request):
"""
Allow an Admin user the ability to setup a patient & visit all at once.
"""
if request.user.is_superuser:
form_class = AdminVisitSetupForm
all_topics = True
else:
form_class = VisitSetupForm
all_topics = False
f = form_class()
# Get a list of topics for each report.
report_topics = {}
for r in Interview.objects.all():
report_topics[r.id] = [t['ad'] for t in r.topics.values('ad')]
data = {
'superuser':request.user.is_superuser,
'report_topics':simplejson.dumps(report_topics)
}
try:
request.user.reviewer
data['reviewer'] = True
except:
pass
if request.method == "POST":
f = form_class(request.POST)
if f.is_valid():
# Create the patient, generate a password, and send them on their way.
cd = f.cleaned_data
patient = None
if cd['revisit']:
# Check for an existing user first.
try:
patient = Patient.objects.get(username=cd['username'])
except Patient.DoesNotExist, e:
data['form'] = f
data['msg'] = 'There is no user with this username.'
return render_to_response('visit/setup.html', data, context_instance=RequestContext(request))
admin_user = get_user(request)
organization = None
if admin_user:
organization = admin_user.organization
if patient and not request.user.is_superuser:
# Make sure the patient they've selected is one of their own.
if patient.organization != organization:
return HttpResponseForbidden('You are not allowed to see this page.')
if not patient:
password = generate_password()
user = User.objects.create_user(cd['username'], cd['contact_email'], password)
user.first_name = cd['first_name']
user.last_name = cd['last_name']
user.save()
patient = Patient(
user=user,
username=user.username,
contact_phone=cd['contact_phone'],
date_of_birth=cd['date_of_birth'],
email=user.email,
first_name=user.first_name,
gender=cd['gender'],
last_name=user.last_name,
maiden_name=cd['maiden_name'],
organization=organization,
patient_type=cd['patient_type'],
security_answer=cd['security_answer'],
security_question=cd['security_question'],
)
patient.save()
# Send them an email.
t = loader.get_template('www/new_account.txt')
c = Context({
'password':'%s-%s-%s' % (password[:3], password[3:5], password[5:]),
'patient':patient
})
msg = t.render(c)
try:
send_mail(
'A request by your physician to do an online medical history before your appointment.',
msg,
'support#careprep.com',
[user.email]
)
except Exception, e:
log.error('Could not send email for new account %s because: [%s]' % (user.username, e))
request.session['password'] = password
# Create the Visit, too.
interview = cd['interview']
list_visit_ids = cd['list_visit_ids']
print list_visit_ids
visit = Visit(
reference_visit = cd['list_visit_ids'],
show_prior_responses = cd['show_prior_responses'],
patient=patient
)
if request.user.is_superuser:
topics = cd['topics']
else:
topics = set(list(interview.topics.all()) + list(cd['topics']))
reviewer_mode = cd.get('reviewer_mode') or patient.patient_type == 'Reviewer'
url, visit = initialize_visit(
request,
patient=patient,
starting_section=interview.starting_section,
visit_title='%s %s' % (patient, interview.title),
topics=topics,
reviewer_mode=reviewer_mode,
chief_complaint=cd['chief_complaint'],
location=cd['interview_site'],
reference_visit = cd['list_visit_ids'],
show_prior_responses = cd['show_prior_responses'],
)
next_url = "/visit/confirmation/%s/%s/?next=%s" % (patient.user.id, interview.id, url)
else:
v = Visit.objects.get(pk=request.POST['list_visit_ids'])
print v
return HttpResponseRedirect(next_url)
# all the fields that are not given pls ignore.
The template is fine.
Now watch forms.py when i do list_visit_ids = ModelChoiceField(queryset=Visit.objects.all(), empty_label='Select Revisit ID',required=False) It works perfectly fine on my local machine.But on my server it has around 6000 visit objects so this page hangs or i should say keep on loading.
So initially i changed it to list_visit_ids = ModelChoiceField(queryset=Visit.objects.none(), empty_label='Select Revisit ID',required=False)
Now i know that by this the form becomes invalid and should go to the else part Now my question how do i make reference_visit=cd['list_visit_ids'] in else (form is invalid)
case save().How do i override the none() attribute.
Thanks in advance i will really appreciate.
If your goal is to save your html page load by removing the 6000 choices (which I've done too: 10000+ <option> fields wrapped by misc html will absolutely choke a page), you shouldn't be using a ChoiceField at all. By setting queryset=Visit.objects.none() you're allowing zero choices and nothing passed in will validate.
You either show 6000 select item drop downs, radio boxes, etc., or find a way to /not/ have a giant select drop down (such as a hidden input or charfield), not fake around a ModelChoiceField who's main purpose is to populate that select drop down and validate.
In short: don't use a ModelChoiceField if you're not going to be using the html choices generated by it. Use something else and do the validation / model pulling yourself via the clean_FOO methods.
class MyForm(forms.Form):
my_input = forms.CharField()
def clean_my_input(self):
input = self.cleaned_data.get('my_input')
try:
return MyModel.objects.get(pk=input) # add a filter here if you want
# (whatever filters you were using in the queryset argument)
except MyModel.DoesNotExist:
raise forms.ValidationError("Doesn't exist / is invalid")
return input