Python Daily
2.57K subscribers
1.48K photos
53 videos
2 files
38.9K links
Daily Python News
Question, Tips and Tricks, Best Practices on Python Programming Language
Find more reddit channels over at @r_channels
Download Telegram
Creating a ModelForm with an arugment

I have some simple models of questions and answers.

#models.py
class Question(models.Model):
question_text = models.CharField(max_length=200)
question_info = models.TextField()

def __str__(self):
return self.question_text

class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
answer_text = models.CharField(max_length=200)
correct = models.BooleanField(default=False)

def __str__(self):
return self.answer_text

I am trying to create a ModelForm that takes all the answers for a given question and displays them with radio buttons. I can do this in views.py and the template just fine.

#views.py
def index(request):
q1 = Question.objects.get(pk=1)
context = {
'q1`': q1,
}
return render(request, 'questions/index.html', context)

\#index.html

<head>
<meta charset="utf-8" />
<title>Django</title>
</head>

<body>
<h1>Welcome!</h1>
<h2> {{ q_1.q_text }}</h2>
<form action="" method="POST">
{% csrf_token %}
{% for answer in q_1.answer_set.all %}
<input type="radio" name="answer" id="answer{{ forloop.counter }} value="{{ answer.id }}" />
<label for="choice{{ forloop.counter }}"> {{ answer.answer_text }} </label></br/>
{% endfor %}
<input type="submit" value="Submit" />
</form>

With this I can't call is_valid() so I tried to make a form for the model.

\#forms.py

class AnswerForm(forms.ModelForm):
class Meta:
model = Answer
a1 = Answer.objects.get(id=1)
a2 = Answer.objects.get(id=2)
a3 = Answer.objects.get(id=3)
a4 = Answer.objects.get(id=4)
a5 = Answer.objects.get(id=5)
fields = [
'correct',
]
widgets = {
'correct': forms.RadioSelect(choices = [
(a1.correct, Answer.objects.get(id=1)),
(a2.correct, Answer.objects.get(id=2)),
(a3.correct, Answer.objects.get(id=3)),
(a4.correct, Answer.objects.get(id=4)),
(a5.correct, Answer.objects.get(id=5))
]
)
}

This allows me to use the is_valid() method for validating the form but it is obviously inefficient as it only works for this one question. I would ideally like to the be able to pass a parameter into the ModelForm so that it uses that value to get the question whether from the id/pk or some other value. My thinking for this would then be that the ModelForm uses lets say id as its argument then I could also set up a url that takes the id of a question also and then when I pass the id in the view along with the request that id also gets used in the ModelForm. So I guess my questions are:

1. Is creating a ModelForm with an arugment for a specific object in the model possible?

2. Is the logic behind using the url id to pass to the ModelForm able to work as well?

Any help is appreciated, Thanks.

/r/djangolearning
http://redd.it/5adqqi
[AF] [Flask-WTF] Flask login form inside Bootstrap modal - how to handle form errors?

I've placed my login form inside a Bootstrap modal. If the form is valid it submits and the user is logged in, but I need a way to display validation errors/failed attempts inside the modal window.

I've only worked with forms that were constrained to one view until now. In those cases I was able to pass the form to the template (`render_template('foo.html', form=form)`) which rendered the fields and handled errors with a [macro][1].

The login modal I'm trying to create sits in the layout view which every template inherits, but the login form isn't passed by every view so the macro can't be used.

Form

class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
password = PasswordField('Password', validators=[DataRequired()])

View

@app.route('/login', methods=['POST'])
def login():
form = forms.LoginForm()
if form.validate_on_submit():
try:
user = models.User.get(models.User.username == form.username.data)
except models.DoesNotExist:
flash("Your username or password doesn't match")
else:
if check_password_hash(user.password, form.password.data):
login_user(user)
flash("You've been logged in!")
return redirect(url_for('index'))
else:
flash("Your username or password doesn't match")

Relevant modal code from layout template

<div class="modal-body">
<form method="post" action='{{ url_for("login") }}' name="LoginForm">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" name="username" id="username" placeholder="Username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" name="password" placeholder="Password"></p>
</div>
<p><button type="submit" class="btn btn-primary">Sign in</button>
<a href="#">Forgot Password?</a>
</p>
</form>
</div>


[1]: http://flask.pocoo.org/docs/0.12/patterns/wtforms/#forms-in-templates

/r/flask
https://redd.it/62nshp
Formatting and tweaking inline formsets

Hey everyone,

I was wondering if anyone had any good ideas on how to format and tweak inline formsets, especially instances when a parent model has multiple, complex children.

As it stands, I can only get inlines to pass through as context by using `inlineformset_factory` in my forms and then passing that formset through in my `get_context_data` as such:

#forms.py

from django.forms.models import inlineformset_factory

LitigantFormset = inlineformset_factory(models.Case, models.Litigant, fields=('person', 'role', 'fine'))
---
#views.py

class CaseEditView(GroupRequiredMixin, UpdateView):

model = models.Case
fields = ['session', 'case_type', 'court_type', 'verdict', 'of_interest', 'ad_legem',
'villeinage_mention', 'active_sale', 'incidental_land', 'summary',]
template_name = 'case/case_edit.html'

group_required = Edit

def get_context_data(self, **kwargs):
context = super(CaseEditView, self).get_context_data(**kwargs)
if self.request.POST:
context['formset'] = forms.LitigantFormset(self.request.POST, instance=self.object)
else:
context['formset'] = forms.LitigantFormset(instance=self.object)
return context

def get_success_url(self):
pk = self.kwargs.get('pk')
return reverse('case', kwargs={'pk': pk})


---
However, when I instantiate the formset in my html template it is ass-ugly, to put it lightly.

I am using [django-widget-tweaks](https://pypi.python.org/pypi/django-widget-tweaks) to modify the template code for my normal forms, but when I try to do any modifications to the formset the debugger informs me that `'LitigantForm' object has no attribute 'form'`. This obviously makes sense, because `LitigantForm` is a context, not a form.

Does anyone have any tricks for formatting inline formsets and working with them in an easy and DRY way?

I would especially like to be able to dynamically add and delete both whole instances, but also add and delete fields within the inline instances themselves (e.g. add a fine to a person or remove it; only having the 'fine' field show when I click an 'add fine' button). This would obviously be js/jquery, but without the ability to individually manipulate the form fields of the inlines, I just don't see how it's possible.

I would really appreciate any pointers or advice! Thanks!

/r/django
https://redd.it/7s8wiw
Problems with Django Autocomplete Light

So, I'm stuck, I'm trying to make two selection boxes, one to select the state, the other to select the city. Both the code and the html are not crashing, but nothing is being loaded into the selection boxes.

Any help would be greatly appreciated!

#models.py
class City(models.Model):
    country = models.CharField(maxlength=50)
    state = models.CharField(max
length=50)
    city = models.CharField(maxlength=50)

    def str(self):
        return f"{
self.name}, {self.state}"
class City(models.Model):
    country = models.CharField(max
length=50)
    state = models.CharField(maxlength=50)
    city = models.CharField(max
length=50)


    def str(self):
        return f"{self.name}, {self.state}"

#forms.py
class CreateUserForm(forms.ModelForm):

    def init(self, args, kwargs):
        super().__init__(
args, kwargs)
        # Ensure city field has proper empty queryset initially


/r/djangolearning
https://redd.it/1kxt7bn