Is it possible to limit choices in SelectModelField in wtf-peewee - python

I use flask with flask-peewee and wtfpeewee.
So, I have models like that:
class Category(Model):
name = CharField()
user = ForeignKeyField(User, null=True)
class Record(Model):
value = DecimalField()
category = ForeignKeyField(Category)
user = ForeignKeyField(User)
When I create form for user to add Record, I do it that way:
RecordForm = model_form(Record)
All categories in database are available for choice in field 'Category' of this form, but I need to limit available choices for 'Category' field to a subset of categories that have user field equal None or current (logged in) user. I know how to limit it by query, but how should that be done for a form field?

Sorry to see this just now
You can do this at class definition time:
from wtfpeewee.fields import SelectQueryField
class MyForm(Form):
category = SelectQueryField(query=Category.filter(some_val=other_val)
Alternatively, I believe you can do this at runtime:
my_form = MyForm()
my_form.category.query = Category.filter(user=some_user)

Related

Trying to use objects from an entirely different model using a foreign key

So I want to assign a 'Rank' to specific users with a Foreign key (I created a model for Ranks with other objects such as an image, description, etc).
What I want to do is to use those objects from the Rank Model and bring them over to my template. So that when I assign the rank "Newbie" to a specific user, it will show all the objects from the Rank like image, and descriptions.
Can anyone help?
Thanks
Here's my views.py
from .models import user as UserModel
def index(request):
return render(request, 'pages/index.html')
def user(request, user_id):
profile = get_object_or_404(UserModel, pk=user_id)
context = {
'profile' : profile,
}
return render(request, 'user/user.html', context)
Here is the model for Ranks
from django.db import models
class Ranks(models.Model):
rank_name = models.CharField(max_length=300)
photo = models.ImageField(upload_to='photos/&Y/%m/%d/')
description = models.TextField(blank=True)
rank_points = models.IntegerField()
rank_promotionss = models.IntegerField()
def __str__(self):
return self.rank_name
It's rather simple - add ForeignKey field to your user model:
class UserModel(models.Model):
...
rank = models.ForeignKey(Ranks, on_delete=models.CASCADE,...)
and then use it in your template simply by calling e.g. profile.rank.rank_name
1 little optimization tip, in your user() method, add select_related column:
def user(request, user_id):
profile = get_object_or_404(UserModel.objects.select_related('rank'), pk=user_id)
or it would perform additional queries to fetch the Rank
Another tip, keep your models names in singular, e.g. Rank instead of Ranks

How save marks in checkboxs?

Can someone say, how create such form as in the picture below in Django?
I have model Product with field is_visable. In form I want to show all products with field is_visable. User can select checkboxes and change the value of is_visable field. In other words make products visable or invisable. I am thing about MultipleChoiceField in my form but not sure is it correct in my case.
models.py:
class Product(models.Model):
symbol = models.CharField(_('Symbol'), max_length=250)
name = models.CharField(_('Name'), max_length=250)
is_visible = models.BooleanField(default=False)
forms.py:
class ProductForm(forms.ModelForm):
product = forms.ModelChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Product.objects.all())
views.py:
if request.method == 'POST':
form = ProductForm(data=request.POST)
if form.is_valid():
ids = form.cleaned_data.get('product') # Example: ['pk', 'pk']
for id in ids:
product = Product.objects.get(pk=id)
product.is_visible = True
product.save()
I think what you want to use is a ModelChoiceField in your form with a widget of CheckboxSelectMultiple.
A queryset for the ModelChoiceField is a required argument, so you can build the queryset like this:
visible_products = Product.objects.filter(is_visible=True)
product_field = forms.ModelChoiceField(queryset=visible_products,
widget=CheckboxSelectMultiple()
See this post for more details:
Django ChoiceField populated from database values

Django Tables 2 limiting fields from form

I am trying to limit the fields to in my table. The only way I see to do it is through the PersonTable object with the field property like this fields = [first_name, last_name]. I want to do it from a request form. I tried to override the get_queryset() method but it did not work only passed in less data but the columns were still there just blank. Is there a good way to do it with the generic view?
class Person(models.Model):
first_name =models.CharField(max_length=200)
last_name =models.CharField(max_length=200)
user = models.ForeignKey("auth.User") dob = models.DateField()
class PersonTable(tables.Table):
class Meta:
model = Person
fields = [first_name, last_name]
class PersonList(SingleTableView):
model = Person
table_class = PersonTable
If anyone runs into this same issue, there is an exclude instance variable on the table class so you can just override get_table and do something like this in your view:
class PersonList(SingleTableView):
model = Person
table_class = PersonTable
template_name = "person.html"
def get_table(self):
table = super(PersonList, self).get_table()
columns = self.request.GET.getlist('column')
tuple_to_exclude = tuple(set(table.columns.names()) - set(columns))
table.exclude = tuple_to_exclude
return table

Finding type of model's field in django

I have a model like this:
class Profile(models.Model):
user = models.OneToOneField("User", verbose_name=u"user", null=True, blank=True, default=None)
monthly_income = models.ForeignKey(MonthlyIncome, verbose_name=u"Monthly Income", null=True, blank=True, default=None)
car = models.ManyToManyField(Car, verbose_name=u"Car?", null=True, blank=True, default=None)
If user changes his profile,these changes saved to another table(UpdateLog). In view I make a query from UpdateLog and if item is in Updatelog, select box would be disable. Because disabled selectboxes doesn't send any data to server, I'm adding the disabled field's value withrequest.POST.copy() as follow view:
in view:
if request.method == "POST":
post_values = request.POST.copy()
query = UpdateLog.objects.filter(user=request.user.id)
for a in query:
field = a.filed_name
try:
sd = eval("profile.%s.id"%field)
post_values.update({field: u"%s"%sd})
except AttributeError:
print field
The problem is: sd = eval("profile.%s.id"%field) is only works for ForeignKey data. I have to separate sd for foreignkey and manytomany fields. How can I recognize type of model's fields in view?
I think you're looking for something like this:
from django.db import models
field_name = a.field_name
field = getattr(profile, field_name)
if isinstance(field, models.Model):
# It's a model object
# (accessing a foreign key returns a model object)
elif isinstance(field, models.manager.Manager):
# It's a manager object
# (accessing a many to many field returns a ManyRelatedManager)
else:
raise ValueError("Unexpected field type")
Consider looking at Django's model options (eg, the Meta class) for a more general solution.
from django.db import models
model_fields = dict((f.name, f) for f in MyModel._meta.fields)
test_field = field_dict[field_name]
if isinstance(test_field, models.OneToOneField):
#it's a one to one field!
elif isinstance(test_field, models.ManyToManyField):
#it's a one to one field!
elif isinstance(test_field, models.IntegerField):
#it's an integer field!
#...
One of the benefits of this approach, outside of generality, is that it doesn't require any database access- it just inspects the schema specified by your model definitions.

Creating an edit form from model containing Foreignkey?

I am creating an app, where I am storing employee's complete information, now the problem with my development is that I am entering dependents of the employee in a manner that the Person which he adds as a dependent gets a entry in the Person model.
Dependent and DependentRelationship Model Look Like:
class Dependent(Person):
"""Dependent models: dependents of employee"""
occupation = models.CharField(_('occupation'), max_length=50, null=True,
blank=True)
self_dependent = models.BooleanField(_('self dependent'))
class DependentRelation(models.Model):
"""Dependent Relation Model for Employee"""
employee = models.ForeignKey(Employee, verbose_name=_('employee'))
dependent = models.ForeignKey(Dependent, verbose_name=_('dependent'))
relationship = models.CharField(_('relationship with employee'),
max_length=50)
class Meta:
ordering = ('employee', 'dependent',)
unique_together = ('employee', 'dependent' )
I am using a ModelForm to enter the data for the dependent this is the form for adding dependent:
class DependentForm(forms.ModelForm):
relationship = forms.CharField(_('relationship')) # TODO: max_length??
class Meta:
model = Dependent
I wanted to show all the Dependent's Information as well as the relationship with the employee, in the edit form. So is there a possible view.
Any suggestions or links can help me a lot.......
Thanks in Advance.....................
#login_required
def edit_dependents(request, id):
employee = request.user.get_profile()
try:
dependent = employee.dependent.get(id=id)
except Dependent.DoesNotExist:
messages.error(request, "You can't edit this dependent(id: %s)." %id)
return HttpResponseRedirect(reverse('core_show_dependent_details'))
dependent_relation = DependentRelation.objects.get(dependent=dependent, employee=employee)
if request.method == "POST":
form = DependentForm(data=request.POST, instance=dependent)
if form.is_valid():
dependent = form.save(commit=False)
dependent_relation = DependentRelation.objects.get(dependent=dependent, employee=employee)
dependent_relation.relationship = form.cleaned_data['relationship']
try:
dependent_relation.full_clean()
except ValidationError, e:
form = DependentForm(data=request.POST)
dependent.save()
dependent_relation.save()
return HttpResponseRedirect(reverse('core_show_dependent_details'))
else:
form = DependentForm(instance=dependent,
initial={'relationship': dependent_relation.relationship})
dictionary = {'form':form,'title':'Edit Dependents',}
return render_to_response('core/create_edit_form.html',dictionary, context_instance = RequestContext(request))
As I have defined my model form in my question, I created an edit form from the same with passing two arguments one is the instance of the dependent person with the query as
dependent = employee.dependent.get(id = id)
where the second id is the dependent's id.
Secondly I saved the relationship in the DependentRelationship model with all its attributes, having the value of relationship, and dependent from the ModelForm.
So in this way I was able to create the edit form for my app. After a long search which is working good.

Categories

Resources