Django query filter by another dataset - python

I have 2 User models:
User: Default user model:
Account: Custom User model, which is an extension of the defualt user model, as I wanted to add a custom field to it called 'Status'.
The problem is that I wanted to filter the data based on the current User, so id usually do something like:
Account.objects.filter(usernmae = User).values_list('status', flat=True)
The problem is that the Account dataset doesnt have the username but they both have the same ID.
I was thinking of doing something like this:
Status = Account.objects.filter(user_id=User.objects.filter(username = user).values_list('id', flat=True)).values_list('status', flat=True)
But then i get the following error:
I imagine there is a way better way of doing it, if yall could help me out.
Views.py:
def upload_audits(request):
form = audits_form(request.POST or None, request.FILES or None)
if form.is_valid():
form.save()
form = audits_form()
obj = Csv_Audit.objects.get(activated=True)
with open(obj.file_name.path,'r') as f:
#to clear model contents before applying new data
auditsModel.objects.all().delete()
reader = csv.reader(f)
for i,row in enumerate(reader):
if i==0:
pass
else:
user = row[1] # gets data from CSV Table and returns username
Status = Account.objects.filter(user_id = request.user).values_list('status')
auditsModel.objects.create(
qs_login = user,
Status = Status,
)
obj.activated = True
obj.save()
return render(request,"backend/uploads.html",{'form':form})
Accounts.py(Model)
class Account(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
status = models.CharField(('Status'), max_length=200, default='',choices = [('Bau','Bau'),('Week 1','Week 1')])
def __str__(self):
return self.user.username
1 Answer:mahdi rahimi
I tried your method with the following code:
Status = Account.objects.filter(user__username = user).values_list('status', flat=True)
Which resulted in the following error:
And then I thought of doing this:
Status = Account.objects.filter(user = user).values_list('status', flat=True)
But i got this error:
Which actually returns the usernmae but it seems to be asking for an int?

based on my experience, you can simply join the two tables, and get what you want. roughly, it translates to this:
result = Account.objects.filter(user__username = user).values_list('status', flat=True)
or you can do two queries if you are comfortable with that.
found_user_id = User.objects.filter(username = user).values_list('id', flat = True)
result = Account.objects.filter(user_id = found_user_id).values_list('status', flat=True)
hope that helped.

Related

How to insert ManyToMany field in django

I want to insert a ManyToMany fields in my db using django.I select some customers using checkboxes.
This is my models.py :
class Campaign(models.Model):
title = models.CharField(max_length=255)
channel = models.CharField(max_length=255)
start_date = models.DateField()
end_date = models.DateField()
target_prospect = models.ManyToManyField(ProspectClient,related_name='campaigns_prospect')
target_partner = models.ManyToManyField(PartnerClient,related_name='campaigns_partners')
I try the code below in my views.py but didn't work :
def campaigns_page(request):
if request.user.is_authenticated:
if request.user.profile == 'D' or request.user.profile == 'E' or request.user.is_superuser:
campaigns = Campaign.objects.all()
prospects = ProspectClient.objects.all()
partners = PartnerClient.objects.exclude(id__in=PartnerClient.objects.values('id')).all()
context = {
'campaigns':campaigns,
'prospects':prospects,
'partners':partners
}
if request.method == 'POST':
title = request.POST['title']
channel = request.POST['channel']
start_date = request.POST['start_date']
end_date = request.POST['end_date']
descriptions = request.POST['goals'].split(",")
targets = request.POST['targets']
campaign = Campaign.objects.create(title=title,channel=channel,start_date=start_date,end_date=end_date)
for description in descriptions:
goal = Goal.objects.create(description=description)
goal.campaign.add(campaign)
for target in targets:
prospects.campaign.add(campaign)
partners.campaign.add(campaign)
return render(request,'CampaignManagement/campaigns_page.html',context)
return render(request, 'Login/logout.html')
If I delete the part of tergets it works.
But with this part it gives me This error : 'QuerySet' object has no attribute 'campaign'
How I can solve this ?
I see a couple of errors. Perhaps one or more are leading to the problem.
One
Try printing this:
partners = PartnerClient.objects.exclude(id__in=PartnerClient.objects.values('id')).all()
print(partners)
I suspect it will print None since you are excluding all id's in PartnerClient.objects.values('id'). On another note you don't need the all() since exclude() will return all the results you are looking for.
Two
In the line for target in targets: what exactly are you iterating through? targets = request.POST['targets'] is just giving you a string, so it would iterate through each letter. Perhaps you meant:
targets = request.POST['targets'].split(", ")
like you did for descriptions? Or perhaps you are getting a list of items from your form, in which case you can use:
targets = request.POST.getlist('targets')

How do I get row from django database?

Hello I am trying to create a clockIn clockOut website and I do not know how to get a row filtered by a persons name to add in the clock out time.
Here is the code. The first if statement is working fine but the else statement is where I am having trouble doing:
if response.POST.get("clockIn"):
if form.is_valid():
n = form.cleaned_data["name"]
t = Name(name = n, timeIn=datetime.now(), timeOut=NULL)
t.save()
else:
if form.is_valid():
n = form.cleaned_data["name"]
t = Name.objects
t = t.filter(name = n)
s = t(timeOut = datetime.now())
s.save()
Here is my models.py:
class Name(models.Model):
name = models.CharField(max_length=200)
timeIn = models.DateTimeField()
timeOut = models.DateTimeField(default=datetime.now())
def __str__(self):
return self.name
if form.is_valid():
n = form.cleaned_data["name"]
# If there are unique entries for this name then you should use get method instead of filter
try:
t = Name.objects.get(name=n)
t.timeOut = datetime.now()
t.save()
except Exception as _: # or maybe NameDoesNotExist exception
# Handle case
pass
You didn't give enough information to solve this issue properly . Where is your models.py file ? You should add models.py file with your question .
By the way , in Django, to get a row using filter is as like as below :
name=your_person_name
Entry.objects.filter(person_name=name)

IntegrityError for AutoField after a bulk_create()

after doing a bulk_create, I'm trying to add some elements to my table but I got an IntegrityError as the sequence still starts with 1 when using save()
Is there any way to update the sequence within Django after the bulk_create ? Or should I generate the id myself using a max filter ?
I'm using a postgre database.
Here is a sample of my code:
elements is a list of Identifiants objects (I'm trying to import the list on a "dump" database first to be sure everything is fine)
try:
Identifiants.objects.using('import-check').all().delete()
Identifiants.objects.using('import-check').bulk_create(elements)
except:
traceback.print_exc()
return False
else:
Identifiants.objects.all().delete()
Identifiants.objects.bulk_create(elements)
return True
And here's the model
class Identifiants(models.Model):
taxon = models.IntegerField(unique=True)
noms = models.TextField(blank=True, null=True)
fiche = models.IntegerField(blank=True, null=True)
sms = models.NullBooleanField()
I let Django create the pk itself
And the view related for further insertions :
elif req.method == 'POST' and req.POST['action'] == "add":
id_form = AddFormId(req.POST)
nom_form = AddFormNom(req.POST)
search_form = LightSearchForm(req.POST)
if id_form.is_valid() and nom_form.is_valid():
inst = id_form.save(commit = False)
num_fiche = Identifiants.objects.all().aggregate(Max('fiche'))['fiche__max']
num_fiche += 1
inst.fiche = num_fiche
inst.save()
values = nom_form.save(commit = False)
values.taxon = inst
values.codesyno = 0
values.save()
return redirect(reverse(details, kwargs = {'id_item' : values.id}))
I got the issue with multiple tables. I always add elements with a form.

django get_or_create method always results in a new record

Model
class projects(models.Model):
"""Table that holds the details of the projects."""
toiName = models.CharField(max_length=100)
toiOwner = models.CharField(max_length=50)
receiver = models.CharField(max_length=50)
manager = models.CharField(max_length=50)
toiOwnerEmail = models.EmailField(max_length=70)
receiverEmail = models.EmailField(max_length=70)
managerEmail = models.EmailField(max_length=70)
dateUpdated= models.DateTimeField(default=datetime.today())
dateCreated = models.DateTimeField(default=datetime.today())
class Meta:
db_table="projects"
View, the original code to save the model works fine, when I go ahead and edit the form in the view, I always end up with a new record.
data = model_to_dict(projects.objects.filter(toiName=pid, managerEmail=request.user)[0])
if request.method == 'POST':
form = projectsForm(request.POST)
if form.is_valid():
#form = projectsForm(request.POST, instance=projects.objects.get(toiName=pid))
#obj = projects\
obj, created = projects.objects.get_or_create\
(toiName=request.POST['toiName'],
toiOwnerEmail=request.POST['toiOwnerEmail'],
toiOwner=request.POST['toiOwner'],
manager=request.POST['manager'],
receiver=request.POST['receiver'],
receiverEmail=request.POST['receiverEmail'],
dateUpdated=datetime.now(),
dateCreated=data['dateCreated'],
managerEmail=request.user,)
Here created always results in True.
At least this dateUpdated=datetime.now() causes get_or_create to always create new record, because each time datetime.now() is different.
I believe I was using the get_or_create incorrectly, since I was only trying to update the entry.
I fixed the code in the view with:
data = model_to_dict(projects.objects.filter(toiName=pid, managerEmail=request.user)[0])
proj = projects.objects.get(toiName=pid, managerEmail=request.user)
if request.method == 'POST':
form = projectsForm(request.POST)
if form.is_valid():
proj.toiName=form.cleaned_data['toiName']
proj.toiOwnerEmail=form.cleaned_data['toiOwnerEmail']
proj.toiOwner=form.cleaned_data['toiOwner']
proj.manager=form.cleaned_data['manager']
proj.receiver=form.cleaned_data['receiver']
proj.receiverEmail=form.cleaned_data['receiverEmail']
proj.dateUpdated=datetime.now()
#proj.dateCreated=data['dateCreated']
proj.save()
additional to #user1865366 answer, projects.objects.get should be enclose it with try ... except ... like so
try:
proj = Projects.objects.get(toiName=pid,manageEmail=request.user)
except Projects.DoesNotExist :
# do something create new proj and do something with the form
...
otherwise there will be big error screen when django cannot get the object

Multiple linked Django forms, one submit

I have models for Application and Role. Role is linked to a FK Role_type, which is linked by FK to Applications that can use those Role_types (this is a bit of an over-simplication for the question, but I think it suffices). I need a way to create a form to make a new Application, and also to create records assigning associated roles to people (although they can be left blank.)
I have gotten as far as creating the form for the Application and having the associated Role-Types appear on the page, with dropdowns to be populated with a user. Hitting submit, though, didn't create any of the associated Role records. All of my research seems to keep coming back to Inline Model Forms, but the docs aren't really making sense to me--the inputs in the example don't seem to correlate to what I need.
I know this may seem like a duplicate, but trust me when I say I've looked at every SO question that seems to relate to this!
EDIT: My POST looks like this: QueryDict: {u'roles-MAX_NUM_FORMS': [u'1000'], u'roles-1-role_type': [u'4'], u'roles-0-user': [u'1'], u'app-owner': [u'1'], u'app-name': [u'1234'], u'app-serviceTier': [u''], u'app-jiraProject': [u''], u'roles-TOTAL_FORMS': [u'2'], u'roles-1-user': [u''], u'roles-0-role_type': [u'3'], u'csrfmiddlewaretoken': [u'eGsDwtsSQJfl0'], u'roles-INITIAL_FORMS': [u'2']}>. Printing RolesFormSet gives me the exact same output (see comment below)
models.py
class Item(models.model):
name = models.CharField(max_length=255)
roles = models.ManyToManyField(User, through='Role')
class Application(Item):
other_assorted_attributes = foo
class RoleType(models.Model):
name = models.CharField(max_length=255)
class ItemTypeRoleMapping(models.Model):
''' pairs role-types (e.g., Developer) with an Item class they are relevant to'''
roleType = models.ForeignKey(RoleType)
itemType = models.CharField(max_length=255, choices=itemChoices)
class Role(models.Model):
role_type = models.ForeignKey(RoleType)
user = models.ForeignKey(User)
item = models.ForeignKey(Item)
views.py
def buildRolesFormset(itemClass):
''' given an item, build a form for all associated roles '''
roleTypesForItem = ItemTypeRoleMapping.objects.all().filter(itemType=itemClass.__name__)
applicable_roles = [{'role_type': roleType} for roleType in roleTypesForItem]
# formset = rolesFormSet(initial=initial, prefix='roles')
RoleFormSet = inlineformset_factory(Application, Role, extra=len(roleTypesForItem), can_delete=False)
formset = RoleFormSet()
for subform, data in zip(formset.forms, applicable_roles):
subform.initial = data
return formset
def new(request):
''' Create a new application '''
user = request.user
# check permission
if request.method == 'POST':
appform = AppForm(request.POST, prefix='app')
if appform.is_valid():
app = appform.save(commit=False)
rolesInlineFormSet = inlineformset_factory(Application, Role)
# pdb.set_trace()
rolesFormSet = rolesInlineFormSet(request.POST, instance=app, prefix='roles')
if rolesFormSet.is_valid():
rolesFormSet.save()
else:
print rolesFormSet.errors
app = appform.save()
# check rolesFormSet
return redirect(reverse('index'))
else:
appform = AppForm(prefix='app')
rolesFormSet = buildRolesFormset(Application)
return render(request, 'who/editapp.html',
{'appform': appform,
'rolesFormSet': rolesFormSet
})
Tricky to tell without more information, but it looks like you're not saving your rolesFormset in the view. You need to call rolesFormset.save() alongside your form.save() call. Additionally, I suppose you want to attach the roles to the created app? Something like this in your view should work:
if request.method == 'POST':
form = AppForm(request.POST)
rolesFormset = RoleForm(request.POST)
if form.is_valid() and rolesFormset.is_valid():
app = form.save()
roles = rolesFormset.save()
for role in roles:
app.roles.add(role)
return redirect(reverse('index'))
Update: Presuming the models.py is out-of-date, and Role does in fact have a foreignKey to User, the problem will be that you're setting a prefix here:
rolesFormSet = rolesInlineFormSet(request.POST, instance=app, prefix='roles')
but not in your buildRolesFormset function. In that function, do:
formset = RoleFormSet(prefix='roles')

Categories

Resources