我整个下午都在冲浪,已经有一段时间了。
我正在尝试弄清楚如果用户驾驶了这种类型的汽车,如何从本质上将外键作为下拉选项。出于示例目的,并使其尽可能简单...
假设我有一个Cars
,Manufacturers
和一个UserProfile
模型。
我有一个Cars
的模型……
class Cars(models.Model):
car_name = models.CharField(max_length=80)
class = models.ForeignKey(Manufacturer,null=True,on_delete=models.DO_NOTHING,related_name='car_manufacturer')
我有一个Manufacturers
的模型……
class Manufacturers(models.Model):
manu_name = models.CharField(max_length=80)
然后我有一个UserProfile
模型。...
class Userprofile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
user_name = models.CharField(max_length=80)
car_owned = models.ForeignKey(Car,null=True,on_delete=models.DO_NOTHING,related_name='car_owned')
到目前为止一切顺利...
我有一个视图,其中列出了所有Manufacturers
,这也很好。它在下面的表格视图中显示了我期望的所有制造商。
class ManufacturerForm(forms.Form):
dropdown = forms.ModelChoiceField(queryset=Manufacturer.objects.all())
def __init__(self, *args, **kwargs):
super(ManufacturerForm, self).__init__(*args, **kwargs)
self.fields['dropdown'].widget.attrs['class'] = 'choices1'
self.fields['dropdown'].empty_label = ''
我正在使用下面的FORMVIEW来显示表单...
class ManufacturerView(LoginRequiredMixin,FormView):
form_class = ManufacturerForm
template_name = 'Directory/HTMLNAME.html'
def get_form_kwargs(self):
kwargs = super(ManufacturerView, self).get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
def form_valid(self, form):
manufacturer = form.cleaned_data['dropdown']
return HttpResponseRedirect(reverse("NAME:manufacturer",kwargs={'pk':manufacturer.pk}))
一切正常。但是,我不知道如何将制造商下拉列表限制为仅用户驾驶的汽车。我试图从本质上将下拉列表限制为仅与基于用户个人资料拥有的汽车相关的制造商。我已经研究了反向查找,并且还尝试了类似于下面概述的方法来解决我的问题...
class ManufacturerForm(forms.Form):
dropdown = forms.ModelChoiceField(queryset=Manufacturer.objects.filter(car_manufacturer=1)
def __init__(self, *args, **kwargs):
super(ManufacturerForm, self).__init__(*args, **kwargs)
self.fields['dropdown'].widget.attrs['class'] = 'choices1'
self.fields['dropdown'].empty_label = ''
但这显然只给我记录Manufacturer
模型的记录1。我试图弄清楚如何仅显示基于个人拥有的数据与单个用户相关的记录。我可以列出所有制造商,然后仅显示ListView
中相关的记录,但是我试图将下拉列表限制为仅ListView
中有相关记录的地方。预先感谢您的任何想法。
答案 0 :(得分:1)
您只错过了几点:
1)以UserProfile
身份通过kwargs['user']
:
kwargs['user'] = UserProfile.objects.get(user=self.request.user)
2)在表单的user
签名中添加__init__
参数,并在此处覆盖dropdown.queryset
:
class ManufacturerForm(forms.Form):
dropdown = forms.ModelChoiceField(queryset=Manufacturer.objects.all())
def __init__(self, user, *args, **kwargs):
super(ManufacturerForm, self).__init__(*args, **kwargs)
self.fields['dropdown'].widget.attrs['class'] = 'choices1'
self.fields['dropdown'].empty_label = ''
self.fields['dropdown'].queryset = Manufacturer.objects.filter(car_manufacturer__car_owned=user)
我也建议您将您的Car - User
关系重写为ManyToMany。如果我正确理解您的信息,则用户可以拥有多辆汽车:
将下拉列表限制为仅显示以下内容的制造商 与汽车 s 有关的用户拥有
如果我理解的正确,您还希望跟踪用户曾经拥有(但现在不再拥有)的汽车。
如果您重写Car - User
关系,那么您可能没有任何理由仅保留其他UserProfile
来保持username
模型。如果是这样,您的models.py
应该如下所示:
class Manufacturer(models.Model):
name = models.CharField(max_length=80)
class Car(models.Model):
name = models.CharField(max_length=80)
klass = models.ForeignKey(Manufacturer, null=True, on_delete=models.DO_NOTHING, related_name='car_manufacturer')
owners = models.ManyToManyField(User, through='Ownership')
class Ownership(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
car = models.ForeignKey(Car, on_delete=models.CASCADE)
active = models.BooleanField(default=True) # True if user owns the car at the moment
答案 1 :(得分:0)
我认为这全都取决于您的订单和模型之间的关系,也许尝试在ManyToMany
和Manufacturer
之间添加Car
关系,这样一个制造商就可以制造许多汽车:>
Class Manufacturer(models.Model):
name = models.CharField(max_length=80)
car = models.ManyToManyField(Car)
然后可能是做某事的情况,例如:
qs = Manufacturer.objects.all(car=user.car_owned)
dropdown = forms.ModelChoiceField(qs)
在您的views.py
文件中:
form = ManufacturerForm(request.POST, user=request.user)
(您可能需要检查以上内容是否有效,因为我不确定Forms是否可以传入请求对象)。
免责声明:我看到您使用的是基于class
的视图...因此,我可能需要调整以上内容。