python - 在视图中动态关联子级和父级
问题描述
我有两个模型,用户模型和测量模型。Measurements 模型通过 ForeignKey 关系与 Usermodel 相关联。我已经成功地创建了允许创建用户的表单,但是希望当您查看这些用户时,您可以从那里创建测量而不指示关系,因为它应该自动使用当前显示的用户模型作为实例并关联它。这一直是个问题。我试着写这样的视图..
视图.py
def client_measurements(request, pk):
measurement = UserModel.objects.get(id=pk)
measurements = measurement.measurements_set.all()
if request.method == 'POST':
form = MeasurementsIForm(request.POST, request.FILES)
if form.is_valid():
form.client_name.client_name = measurement.client_name
measure = form.save(commit=False)
measure.instance = measurement
measure.save()
return HttpResponseRedirect(reverse_lazy('client', args= [measurement.id]))
else:
form = MeasurementsIForm()
return render(request, 'app/measurements.html', {'form':form, 'measurements': measurements, 'measurement': measurement})
这不会保存到数据库。我是 django 的新手,请问我做错了什么?
模型.py
class UserModel(models.Model):
user_name = models.ForeignKey(User, on_delete=models.CASCADE)
client_name = models.CharField(max_length=100)
# client_lname = CapitalizeCharField(max_length=100, null=True, blank=True)
address = models.CharField(max_length=500, null=True, blank=True)
MALE = 'Male'
FEMALE = 'Female'
sex = (
(MALE, 'Male'),
(FEMALE, 'Female'),
)
client_gender = models.CharField(
max_length=100,
choices=sex,
null=True
)
tel = models.CharField(max_length=100, null=True, blank=True)
date = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return self.client_name
image = models.ImageField(upload_to=image_upload, null=True, blank=True)
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
if self.image:
img = Image.open(self.image.path)
if img.width > 800 or img.height > 534:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)
def get_absolute_url(self):
return reverse('client', kwargs={'pk': self.id})
class Measurements(models.Model):
user_name = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
client_name = models.ForeignKey(UserModel, on_delete=models.CASCADE)
DRESS = 'Dress'
SHIRT = 'Shirt'
TOUSERS = 'Trousers'
SKIRT = 'Skirt'
ATIRE = 'Native Atire'
GOWN = 'Gown'
dress_type = (
(DRESS, 'Dress'),
(SHIRT, 'Shirt'),
(TOUSERS, 'Trousers'),
(SKIRT, 'Skirt'),
(ATIRE, 'Atire'),
(GOWN, 'Gown'),
)
cloth_type = models.CharField(
max_length=100,
choices=dress_type,
null=True
)
neck = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
over_bust = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
bust = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
under_bust = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
chest = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
crutch_depth = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
ankle = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
inseam = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
total_height = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
waist = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
hips = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
neck_to_heel = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
neck_to_above_knee = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
above_knee_to_ankle = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
arm_length = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
trouser_length = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
shoulder_seem = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
arm_hole = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
bicep = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
fore_arm = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
wrist = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
v_neck_cut = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
shoulder_to_waist = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
waist_to_above_knee = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
comment = models.TextField(null=True, blank=True)
date = models.DateTimeField(auto_now_add=True, null=True)
measurement_image = models.ImageField(upload_to=measurement_image_upload, null=True, blank=True)
表格.py
class ClientForm(forms.ModelForm):
client_name = forms.RegexField(regex=re.compile(r'[A-Z][a-z]+((\s[A-Z]([a-z]+)?)?)((\s[A-Z]([a-z]+)?)?)'), required=True, error_messages={'invalid': "Each name must be Capitalized. E.g 'Kelly Roland' not 'kelly roland'"}, label="Client's Full Name")
tel = forms.RegexField(regex=re.compile(r'(080|090|070|081)[0-9]{8}'), required=False, error_messages={'invalid': "Enter a valid phone number"}, label="Phone No")
class Meta:
model = UserModel
widgets = {
"tel": TextInput(),
"client_name": TextInput(attrs={"placeholder": "Emanuel Felix Johnson"})
}
labels = {
"client_name": "Client's FullName",
"tel": "Phone No",
"client_gender": "Gender"
}
fields = ('client_name', 'client_gender', 'address', 'tel', 'image' )
class MeasurementsIForm(forms.ModelForm):
class Meta:
model = Measurements
fields = '__all__'
exclude = ['user_name', 'client_name']
解决方案
这就是我如何改变你的观点来做你想做的事。请注意,模板上下文现在的客户端密钥是 user 而不是measurement
.
def client_measurements(request, pk):
client = UserModel.objects.prefetch_related('measurements_set').get(id=pk)
measurements = client.measurements_set.all()
if request.method == 'POST':
form = MeasurementsIForm(request.POST, request.FILES)
if form.is_valid():
measurement = form.save(commit=False)
measurement.client_name = client
measurement.save()
return HttpResponseRedirect(reverse_lazy('client', args= [measurement.id]))
else:
form = MeasurementsIForm()
return render(request, 'app/measurements.html', {'form':form, 'measurements': measurements, 'client': client})
顺便说一句,我强烈建议将您的测量模型更改为:
class Measurement(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
client = models.ForeignKey(UserModel, on_delete=models.CASCADE)
应该命名 ForeignKey 属性,以便表示相关模型实例,而不是它们的属性。使用 ORM 时,您应该利用抽象而不是对抗它们。
推荐阅读
- c# - 在个人调用中排除子实体
- excel - Excel - 数据透视图 - 计算开始时间和结束时间是否落入时间段
- html - 在css中更改输入搜索表单的背景颜色
- android - 如何在单击 LinearLayout 中的另一个 Textview 时使所有 TextView 不可见
- dbeaver - DBeaver 不显示 dbms_output
- regex - 如何在vim中匹配“\n”?
- symfony - Symfony 3.4记住我重启浏览器后不工作
- hive - Hive 相当于 LISTAGG
- vba - VBA宏:按位置查找按钮并“单击”它们
- ios - 在 Xcode 中尝试从终端构建项目时出现以下错误