问题
I'm trying to create an object in Django using the standard class based views and form libraries. Three fields in my form are dependent upon a domain variable captured from the URL pattern. My questions are:
- How do I access
domain
withinCreateSubscription
so that I can setSubscription.site
toSite.objects.filter(domain=domain)[0]
? - How do I limit the dropdown fields rendered from
CreateSubscriptionForm
so thatplan
displays onlySubscriptionPlan.objects.filter(site=Site.objects.filter(domain=domain)[0])
andpayment_profile
is limited toPaymentProfile.objects.filter(user=request.user)
?
For clarity's sake, the domain in r'^subscribe/(?P<domain>\w+\.\w+)/$'
is unrelated to my own site's domain. The django.contrib.sites
framework won't help me here.
Thanks in advance for helping me untangle all of these CBV methods. :)
The URL pattern is:
from django.conf.urls import patterns, url
from accounts.views import *
url(r'^subscribe/(?P<domain>\w+\.\w+)/$',
CreateSubscription.as_view(), name='subscribe_to_site'),
)
The view in question is:
from accounts.forms import *
from accounts.models import *
class CreateSubscription(CreateView):
model = Subscription
form_class = CreateSubscriptionForm
def form_valid(self, form):
form.instance.user = self.request.user
return super(CreateSubscription, self).form_valid(form)
The relevant models are:
from django.conf import settings
from django.contrib.sites.models import Site
from django.db import models
class PaymentProfile(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
class SubscriptionPlan(models.Model):
site = models.ForeignKey(Site)
name = models.CharField(max_length=40)
class Subscription(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
site = models.ForeignKey(Site)
plan = models.ForeignKey(SubscriptionPlan)
payment_profile = models.ForeignKey(PaymentProfile)
And, finally, my form is:
from accounts.models import *
class CreateSubscriptionForm(forms.ModelForm):
class Meta:
model = Subscription
exclude = ('user', 'site', )
回答1:
To access the data passed to the view, use self.args
and self.kwargs
from accounts.forms import *
from accounts.models import *
class CreateSubscription(CreateView):
model = Subscription
form_class = CreateSubscriptionForm
def form_valid(self, form):
form.instance.user = self.request.user
form.instance.site = Site.objects.get(domain=self.kwargs['domain'])
return super(CreateSubscription, self).form_valid(form)
To restrict the dropdown content, you need to set the queryset
for those fields. Very basically, something along these lines:
class CreateSubscriptionForm(forms.ModelForm):
plan = forms.ModelChoiceField(
queryset=SubscriptionPlan.objects.filter(xxx)
)
...
class Meta:
model = Subscription
exclude = ('user', 'site', )
This can also be done inside the view so that you have access to the domain.
class CreateSubscription(CreateView):
model = Subscription
form_class = CreateSubscriptionForm
def get_form(self, form_class):
"""
Returns an instance of the form to be used in this view.
"""
form = super(CreateSubscription, self).get_form(form_class)
form.fields['plan'].queryset = SubscriptionPlan.objects.filter(site__domain=self.kwargs['domain'])
return form
...
def form_valid(self, form):
form.instance.user = self.request.user
form.instance.site = Site.objects.get(domain=self.kwargs['domain'])
return super(CreateSubscription, self).form_valid(form)
来源:https://stackoverflow.com/questions/15511941/django-accessing-url-variables-in-class-based-views-and-forms