Random Option In Django Drop Down Form - python

I've been picking my brain trying to figure this out and so now I turn to the community for help.
I'm using models to create a form in Django and I want to add a Random option to a few of the drop-down choices.
Here is a general idea of what I'm working with:
models.py
Character(models.Model):
name = models.CharField(max_length=255,unique=True)
age = models.PositiveIntegerField(default=0)
gender = models.CharField(max_length=20,choices=creation_choices.GENDERS)
race = models.CharField(max_length=500,choices=creation_choices.RACE)
creation_choices.py
GENDERS = (
('male',"Male"),
("female","Female"),
("unknown","Unknown"),
)
RACE = (
('human','Human'),
('elf','Elf'),
('dwarf','Dwarf'),
)
What I am trying to do is add a way for users to select Random and it returns one of the other values. I tried a lot of different methods but most returned an error. When I created a function with random.choice() and pushed that through it seemed to work, but for some reason always returned the same value.
Any help would be greatly appreciated!

add (None,'Random') to choice sets and on the model-fields in question declare
default=select_random_gender and default=select_random_race as well as blank=False, null=False.
declare these functions:
def select_random_gender():
selection = random.choice(GENDERS)[0]
return selection if selection else select_random_gender()
def select_random_race():
selection = random.choice(RACE)[0]
return selection if selection else select_random_race()

Related

Django if elif else statement

I'm trying to print the result according to the user's age selection in the form, but my if,elif and else statements are not working.
class Quiz(models.Model):
age_choices = (('10-12', '10-12'),
('13-16', '13-16'),
('17-20', '17-20'),
('21-23','21-23'),
)
age = models.CharField(max_length = 100, choices = age_choices)
views.py
def create_order(request):
form = QuizForm(request.POST or None)
if request.method == 'POST':
quiz = Quiz.objects
if quiz.age=='10-12':
print("10-12")
elif quiz.age=='13-16':
print("13-16")
elif quiz.age=='17-20':
print("17-20")
elif quiz.age=='21-23':
print("21-23")
else:
return None
context = {'form':form}
return render(request, "manualupload.html", context)
quiz = Quiz.objects will return a django.db.models.manager.Manager object and this can be further used to fetch the objects from database belonging to that particular model. The appropriate query set will be quiz = Quiz.objects.all() Then you will get the list of all objects in that belong to Quiz model. Once you get list of all objects, you can get the specific object either by indexing or by filtering using a specific query that you need to look into and then for that particular object you can get the age property.
Refer to official django documentation about creating queries for more information.
As #Abhijeetk431 mentioned, your issue lies in quiz = Quiz.objects.
If you use type(quiz), you will find that it outputs django.db.models.manager.Manager. This is not what you want, as age is a property of the Quiz class, not the Manager class.
For starters, refer to this.
This will return you a Queryset list, something akin to an Excel table. age is akin to the column in the table. To get age, what you want is the row (the actual Quiz object) in said table, which you can achieve using get or using the square brackets [].
Thus, your code should look something like this:
Model.objects.all()[0]
That would return the correct object(only the first row) and allow you to get the column value.
However, further clarification will be needed though, to know exactly what your problem is aside from 'it doesn't work'. How did you know your code is not working; what did the debugger tell you?

Django Python Where to add Auxiliary Functions to not repeat code?

I come from native POO programming languages and I'm new in Python, also Django.
I see that in Django they put all code from an app in same views.py or models.py.
Now I'm in a view called:
def create_ticket(self):
....
And inside I have this code
is_staff=User.objects.get(pk=request.user.id).is_staff
if is_staff==1:
R_Client_Accountant = LinkUserContable.objects.filter(contable=mongoId)
print(R_Client_Accountant)
accountantList = []
for relation in R_Client_Accountant:
try:
rmongosql = RMongoSql.objects.get(mongoId=relation.user.id)
user = User.objects.get(pk=rmongosql.helpdeskId)
accountantList.append((user.id,user.username))
except:
pass
else:
R_Client_Accountant = LinkUserContable.objects.filter(user=mongoId)
accountantList = []
for relation in R_Client_Accountant:
try:
rmongosql = RMongoSql.objects.get(mongoId=relation.contable.id)
user = User.objects.get(pk=rmongosql.helpdeskId)
accountantList.append((user.id,user.username))
except:
pass
As you can see I repeat code inside the 'try' just exchanging {user XOR contable}
If I want to write a function passing by parameter this {user XOR contable} where should I place it ?
To me, in corresponding model from models.py is not correct because there are so much code lines referring to different models and views.py is just for view functions right ?
Regards,
VĂ­ctor.
you can use the getattr function to use a string to get the required attribute getattr(relation, relation_attr)
your function would look like this
def create_ticket(self):
is_staff=User.objects.get(pk=request.user.id).is_staff
if is_staff==1:
relation_attr = 'user'
else:
relation_attr = 'contable'
R_Client_Accountant = LinkUserContable.objects.filter(contable=mongoId)
print(R_Client_Accountant)
accountantList = []
for relation in R_Client_Accountant:
try:
rmongosql = RMongoSql.objects.get(mongoId=getattr(relation, relation_attr).id)
user = User.objects.get(pk=rmongosql.helpdeskId)
accountantList.append((user.id, user.username))
except:
pass

How to implement forms for sets and supersets of objects with Django

Imagine the following two Django models:
class Item(models.Model):
'''
A single Item of something.
'''
name = models.CharField(unique = True)
sets = model.ManyToManyField('Set', blank = True)
def get_supersets(self):
'''
Returns the list of all the supersets the item belongs to EXCLUDING the
directly linked sets.
'''
res = []
for set in self.sets:
res = res + set.get_all_supersets()
return res
class Set(models.Model):
'''
A set of items wich can either contain items or not (empty set allowed).
Sets can be grouped in supersets. Supersets will contain all items of
the related subsets.
'''
name = models.CharField(unique = True)
superset = models.ForeignKey('self', on_delete = models.SET_NULL, null = True, blank = True)
# Note: Self-reference to the same object is avoided by excluding it
from the forms queryset for the superset field.
def get_all_spersets(self):
'''
Returns all supersets of the set.
'''
if self.superset:
return [self.superset] + self.superset.get_all_supersets()
else:
return []
I found two options for implementing the connection between supersets and the corresponding items of the sets in a given superset:
On saving a set or an item update the item_set of the supersets. With this, all relations will be stored in the database. This also needs to include some logic regarding circular relations.
Decide for "direct-links-only", which means an item will only be linked to its directly related set in the database. The relations to the supersets will be found on the fly if requested (e.g get all supersets) with model methods.
For me, option 2 seems much more attractive in terms of data integrity since connected relations will be updated on the fly. However, once a user enters an item -> set relation one needs to make sure the user does not unnecessarily select a superset of a set the item already belongs to, which would break the logic and in the worst case lead to infinite recursion in the model methods to retrieve the supersets.
Since the selection will take place in a form, the Item form looks like this:
class ItemForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.fields['sets'].queryset = Set.objects.all()
# For now, this shows all available sets. One could limit this
queryset to only the sets not in the items get_superset().
However, this would not allow the user to see wich supersets
the item already belongs to.
class Meta:
model = Item
widgets = {'sets': forms.CheckboxSelectMultiple()}
# Available sets are shown as checkboxes.
The Set form looks like this:
class SetForm(forms.ModelForm):
def __init__(self):
self.fields['superset'].queryset = Set.objects.all.exclude(id__exact=self.instance.id)
# As mentioned, avoiding self-reference.
class Meta:
model = Set
My question:
1) How can I show the Items supersets in the ItemForm but avoid that a user chooses them?
2) If a user chooses a set, wich is part of a superset, this superset should immediately become unavailable in the ItemForm. Is something like this possible and how?

hierarchal permission on same model

Sorry, I couldn't find a suitable title, please edit the title if you understood the problem.
I want to achieve 4 level hierarchy (django Group): Country-Manager,State-Manager, City-Manager and Field-staff.
One user can belong to only one group at a time and any user can add a lead.
I have a model named Lead and I want to realize the following hierarchy:
"User of higher level (say State-Manager) can view leads added by him and and all entries added by users of lower level (say City-Manager and Field Staff) but can not view entries added by other users of same level or higher lever (say Country-Manager)"
To keep track who has added the entry, I am saving user and Group object as foreign key in the Lead model.
Please suggest any strategy or code snippet.
--
p.s: I am on Django 1.5
I solved this problem with help of mixins. ( http://eflorenzano.com/blog/2008/05/17/exploring-mixins-django-model-inheritance/ )
for I create a Hierarchy class:
class Hierarchy(models.Model):
parent = models.ForeignKey('self',null=True,blank=True)
def get_children(self):
return self._default_manager.filter(parent=self)
def get_descendants(self):
descs = set(self.get_children())
for node in list(descs):
descs.update(node.get_descendants())
return descs
class Meta:
abstract = True
and inherited it in class named GroupHirerarchy:
class GroupHierarchy(Hierarchy):
group = models.ForeignKey(Group)
def __unicode__(self):
return self.group.name
Now I can get children of a group using
group_object.get_children()
and all descendants by :
group_object.get_descendants()
Now using this I achieve get hierarchical permission on model:
glist = []
groups = request.user.groups.all()
for group in groups:
try:
group_hierarchy = GroupHierarchy.objects.get(group = group)
group_descendants = group_hierarchy.get_descendants()
for group_descendant in group_descendants:
glist.append(Group.objects.get(name=group_descendant.group))
except:
pass
obj = Model.objects.filter(user_group__in = glist)

Django - How to make a form for a model's foreign keys?

Here's what I'm trying to do. I'm wondering if someone can suggest a good approach:
models.py:
class Color(models.Model):
name = models.CharField(...
class Speed(models.Model):
name = models.CharField(...
class Dog(models.Model):
name = models.CharField(...
color = models.ForeignKey(Color...
speed = models.ForeignKey(Speed...
class DogRequest(models.Model):
dog = models.ForeignKey(Dog...
request_time = models.DateTimeField()
Now I want to have a page where a user can enter or edit a DogRequest, but the form should look like this:
Enter Dog Request:
---------------------
color (dropdown V)
speed (dropdown V)
|save|
So how would I design that form in the view? The problem is the user will be entering properties of a dog, but not a dog. So I need to find or create a dog record depending on what the user enters.
So far I've tried something like this:
class DogRequestForm(ModelForm):
class Meta:
model = DogRequest
fields = ('request_time','color','speed')
color = forms.ModelChoiceField(queryset=Color.objects.all())
speed = forms.ModelChoiceField(queryset=Speed.objects.all())
Now assuming that even works, where do I put the code to figure out the Dog record to use (or create) depending on what's entered for color and speed? And how do I fill the form from a DogRequest?
I don't think you want to use a ModelForm here. It will never be valid without some hackery, since you won't have found or created the dog object before calling is_valid().
Instead, I'd just use a regular form, and then override the save method of DogRequest to find or create the dog.
Update: Responding to the followup question in the comment, I haven't tested this, but something like it should work.
class DogRequestForm(forms.Form):
id = forms.IntegerField(required=False, widget=forms.HiddenInput())
color = forms.ModelChoiceField(queryset=Color.objects.all())
speed = forms.ModelChoiceField(queryset=Speed.objects.all())
and then when you create an instance of this form for your edit view you need to instantiate it with something like this:
data = {
'id': dog_request_id,
'color': dog_color,
'speed': dog_speed,
}
form = DogRequestForm(data)
where you populate the current dog_request_id, dog_color and dog_speed from your existing DogRequest object.

Categories